28 #include "my_global.h"                           
   34 #include "sql_table.h"                          
   35 #include "hash_filo.h" 
   36 #include "sql_parse.h"                           
   40 #include "rpl_filter.h"            
   45 #include "transaction.h" 
   48 #include <sql_common.h> 
   50 #include "sql_connect.h" 
   53 #include <mysql/plugin_validate_password.h> 
   55 #include "crypt_genhash_impl.h" 
   57 #if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) 
   58 #include <openssl/rsa.h> 
   59 #include <openssl/pem.h> 
   60 #include <openssl/err.h> 
   66 bool mysql_user_table_is_in_short_password_format= 
false;
 
   67 my_bool disconnect_on_expired_password= TRUE;
 
   68 bool auth_plugin_is_built_in(
const char *plugin_name);
 
   69 bool auth_plugin_supports_expiration(
const char *plugin_name);
 
   70 void optimize_plugin_compare_by_pointer(
LEX_STRING *plugin_name);
 
   75     { C_STRING_WITH_LEN(
"Host") },            
 
   76     { C_STRING_WITH_LEN(
"char(60)") },
 
   80     { C_STRING_WITH_LEN(
"Db") },            
 
   81     { C_STRING_WITH_LEN(
"char(64)") },
 
   85     { C_STRING_WITH_LEN(
"User") },
 
   86     { C_STRING_WITH_LEN(
"char(16)") },
 
   90     { C_STRING_WITH_LEN(
"Select_priv") },
 
   91     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
   92     { C_STRING_WITH_LEN(
"utf8") }
 
   95     { C_STRING_WITH_LEN(
"Insert_priv") },
 
   96     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
   97     { C_STRING_WITH_LEN(
"utf8") }
 
  100     { C_STRING_WITH_LEN(
"Update_priv") },
 
  101     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  102     { C_STRING_WITH_LEN(
"utf8") }
 
  105     { C_STRING_WITH_LEN(
"Delete_priv") },
 
  106     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  107     { C_STRING_WITH_LEN(
"utf8") }
 
  110     { C_STRING_WITH_LEN(
"Create_priv") },
 
  111     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  112     { C_STRING_WITH_LEN(
"utf8") }
 
  115     { C_STRING_WITH_LEN(
"Drop_priv") },
 
  116     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  117     { C_STRING_WITH_LEN(
"utf8") }
 
  120     { C_STRING_WITH_LEN(
"Grant_priv") },
 
  121     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  122     { C_STRING_WITH_LEN(
"utf8") }
 
  125     { C_STRING_WITH_LEN(
"References_priv") },
 
  126     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  127     { C_STRING_WITH_LEN(
"utf8") }
 
  130     { C_STRING_WITH_LEN(
"Index_priv") },
 
  131     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  132     { C_STRING_WITH_LEN(
"utf8") }
 
  135     { C_STRING_WITH_LEN(
"Alter_priv") },
 
  136     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  137     { C_STRING_WITH_LEN(
"utf8") }
 
  140     { C_STRING_WITH_LEN(
"Create_tmp_table_priv") },
 
  141     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  142     { C_STRING_WITH_LEN(
"utf8") }
 
  145     { C_STRING_WITH_LEN(
"Lock_tables_priv") },
 
  146     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  147     { C_STRING_WITH_LEN(
"utf8") }
 
  150     { C_STRING_WITH_LEN(
"Create_view_priv") },
 
  151     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  152     { C_STRING_WITH_LEN(
"utf8") }
 
  155     { C_STRING_WITH_LEN(
"Show_view_priv") },
 
  156     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  157     { C_STRING_WITH_LEN(
"utf8") }
 
  160     { C_STRING_WITH_LEN(
"Create_routine_priv") },
 
  161     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  162     { C_STRING_WITH_LEN(
"utf8") }
 
  165     { C_STRING_WITH_LEN(
"Alter_routine_priv") },
 
  166     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  167     { C_STRING_WITH_LEN(
"utf8") }
 
  170     { C_STRING_WITH_LEN(
"Execute_priv") },
 
  171     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  172     { C_STRING_WITH_LEN(
"utf8") }
 
  175     { C_STRING_WITH_LEN(
"Event_priv") },
 
  176     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  177     { C_STRING_WITH_LEN(
"utf8") }
 
  180     { C_STRING_WITH_LEN(
"Trigger_priv") },
 
  181     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  182     { C_STRING_WITH_LEN(
"utf8") }
 
  189     { C_STRING_WITH_LEN(
"Host") },            
 
  190     { C_STRING_WITH_LEN(
"char(60)") },
 
  194     { C_STRING_WITH_LEN(
"User") },            
 
  195     { C_STRING_WITH_LEN(
"char(16)") },
 
  199     { C_STRING_WITH_LEN(
"Password") },            
 
  200     { C_STRING_WITH_LEN(
"char(41)") },
 
  201     { C_STRING_WITH_LEN(
"latin1") }
 
  204     { C_STRING_WITH_LEN(
"Select_priv") },
 
  205     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  206     { C_STRING_WITH_LEN(
"utf8") }
 
  209     { C_STRING_WITH_LEN(
"Insert_priv") },
 
  210     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  211     { C_STRING_WITH_LEN(
"utf8") }
 
  214     { C_STRING_WITH_LEN(
"Update_priv") },
 
  215     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  216     { C_STRING_WITH_LEN(
"utf8") }
 
  219     { C_STRING_WITH_LEN(
"Delete_priv") },
 
  220     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  221     { C_STRING_WITH_LEN(
"utf8") }
 
  224     { C_STRING_WITH_LEN(
"Create_priv") },
 
  225     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  226     { C_STRING_WITH_LEN(
"utf8") }
 
  229     { C_STRING_WITH_LEN(
"Drop_priv") },
 
  230     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  231     { C_STRING_WITH_LEN(
"utf8") }
 
  234     { C_STRING_WITH_LEN(
"Reload_priv") },
 
  235     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  236     { C_STRING_WITH_LEN(
"utf8") }
 
  239     { C_STRING_WITH_LEN(
"Shutdown_priv") },
 
  240     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  241     { C_STRING_WITH_LEN(
"utf8") }
 
  244     { C_STRING_WITH_LEN(
"Process_priv") },
 
  245     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  246     { C_STRING_WITH_LEN(
"utf8") }
 
  249     { C_STRING_WITH_LEN(
"File_priv") },
 
  250     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  251     { C_STRING_WITH_LEN(
"utf8") }
 
  254     { C_STRING_WITH_LEN(
"Grant_priv") },
 
  255     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  256     { C_STRING_WITH_LEN(
"utf8") }
 
  259     { C_STRING_WITH_LEN(
"References_priv") },
 
  260     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  261     { C_STRING_WITH_LEN(
"utf8") }
 
  264     { C_STRING_WITH_LEN(
"Index_priv") },
 
  265     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  266     { C_STRING_WITH_LEN(
"utf8") }
 
  269     { C_STRING_WITH_LEN(
"Alter_priv") },
 
  270     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  271     { C_STRING_WITH_LEN(
"utf8") }
 
  274     { C_STRING_WITH_LEN(
"Show_db_priv") },
 
  275     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  276     { C_STRING_WITH_LEN(
"utf8") }
 
  279     { C_STRING_WITH_LEN(
"Super_priv") },
 
  280     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  281     { C_STRING_WITH_LEN(
"utf8") }
 
  284     { C_STRING_WITH_LEN(
"Create_tmp_table_priv") },
 
  285     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  286     { C_STRING_WITH_LEN(
"utf8") }
 
  289     { C_STRING_WITH_LEN(
"Lock_tables_priv") },
 
  290     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  291     { C_STRING_WITH_LEN(
"utf8") }
 
  294     { C_STRING_WITH_LEN(
"Execute_priv") },
 
  295     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  296     { C_STRING_WITH_LEN(
"utf8") }
 
  299     { C_STRING_WITH_LEN(
"Repl_slave_priv") },
 
  300     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  301     { C_STRING_WITH_LEN(
"utf8") }
 
  304     { C_STRING_WITH_LEN(
"Repl_client_priv") },
 
  305     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  306     { C_STRING_WITH_LEN(
"utf8") }
 
  309     { C_STRING_WITH_LEN(
"Create_view_priv") },
 
  310     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  311     { C_STRING_WITH_LEN(
"utf8") }
 
  314     { C_STRING_WITH_LEN(
"Show_view_priv") },
 
  315     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  316     { C_STRING_WITH_LEN(
"utf8") }
 
  319     { C_STRING_WITH_LEN(
"Create_routine_priv") },
 
  320     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  321     { C_STRING_WITH_LEN(
"utf8") }
 
  324     { C_STRING_WITH_LEN(
"Alter_routine_priv") },
 
  325     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  326     { C_STRING_WITH_LEN(
"utf8") }
 
  329     { C_STRING_WITH_LEN(
"Create_user_priv") },
 
  330     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  331     { C_STRING_WITH_LEN(
"utf8") }
 
  334     { C_STRING_WITH_LEN(
"Event_priv") },
 
  335     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  336     { C_STRING_WITH_LEN(
"utf8") }
 
  339     { C_STRING_WITH_LEN(
"Trigger_priv") },
 
  340     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  341     { C_STRING_WITH_LEN(
"utf8") }
 
  344     { C_STRING_WITH_LEN(
"Create_tablespace_priv") },
 
  345     { C_STRING_WITH_LEN(
"enum('N','Y')") },
 
  346     { C_STRING_WITH_LEN(
"utf8") }
 
  349     { C_STRING_WITH_LEN(
"ssl_type") },
 
  350     { C_STRING_WITH_LEN(
"enum('','ANY','X509','SPECIFIED')") },
 
  351     { C_STRING_WITH_LEN(
"utf8") }
 
  354     { C_STRING_WITH_LEN(
"ssl_cipher") },
 
  355     { C_STRING_WITH_LEN(
"blob") },
 
  359     { C_STRING_WITH_LEN(
"x509_issuer") },
 
  360     { C_STRING_WITH_LEN(
"blob") },
 
  364     { C_STRING_WITH_LEN(
"x509_subject") },
 
  365     { C_STRING_WITH_LEN(
"blob") },
 
  369     { C_STRING_WITH_LEN(
"max_questions") },
 
  370     { C_STRING_WITH_LEN(
"int(11)") },
 
  374     { C_STRING_WITH_LEN(
"max_updates") },
 
  375     { C_STRING_WITH_LEN(
"int(11)") },
 
  379     { C_STRING_WITH_LEN(
"max_connections") },
 
  380     { C_STRING_WITH_LEN(
"int(11)") },
 
  384     { C_STRING_WITH_LEN(
"plugin") },
 
  385     { C_STRING_WITH_LEN(
"char(64)") },
 
  389     { C_STRING_WITH_LEN(
"authentication_string") },
 
  390     { C_STRING_WITH_LEN(
"text") },
 
  396   mysql_db_table_def= {MYSQL_DB_FIELD_COUNT, mysql_db_table_fields};
 
  399   mysql_user_table_def= {MYSQL_USER_FIELD_COUNT, mysql_user_table_fields};
 
  401 static LEX_STRING native_password_plugin_name= {
 
  402   C_STRING_WITH_LEN(
"mysql_native_password")
 
  406   C_STRING_WITH_LEN(
"mysql_old_password")
 
  410   C_STRING_WITH_LEN(
"sha256_password")
 
  413 static LEX_STRING validate_password_plugin_name= {
 
  414   C_STRING_WITH_LEN(
"validate_password")
 
  419 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
  424 #define WARN_DEPRECATED_41_PWD_HASH(thd) \ 
  425   WARN_DEPRECATED(thd, "pre-4.1 password hash", "post-4.1 password hash") 
  432   uint hostname_length;
 
  435   const char *calc_ip(
const char *ip_arg, 
long *val, 
char end)
 
  438     if (!(ip_arg=str2int(ip_arg,10,0,255,&ip_val)) || *ip_arg != 
'.')
 
  441     if (!(ip_arg=str2int(ip_arg+1,10,0,255,&tmp)) || *ip_arg != 
'.')
 
  444     if (!(ip_arg=str2int(ip_arg+1,10,0,255,&tmp)) || *ip_arg != 
'.')
 
  447     if (!(ip_arg=str2int(ip_arg+1,10,0,255,&tmp)) || *ip_arg != end)
 
  454   const char *get_host()
 const { 
return hostname; }
 
  455   int get_host_len() { 
return hostname_length; }
 
  459     return (strchr(hostname,wild_many) ||
 
  460             strchr(hostname,wild_one)  || ip_mask );
 
  463   bool check_allow_all_hosts()
 
  466             (hostname[0] == wild_many && !hostname[1]));
 
  476     hostname=(
char*) host_arg;     
 
  477     hostname_length= hostname ? strlen( hostname ) : 0;
 
  479         (!(host_arg=(
char*) calc_ip(host_arg,&ip,
'/')) ||
 
  480          !(host_arg=(
char*) calc_ip(host_arg+1,&ip_mask,
'\0'))))
 
  504   bool compare_hostname(
const char *host_arg, 
const char *ip_arg)
 
  507     if (ip_mask && ip_arg && calc_ip(ip_arg,&tmp,
'\0'))
 
  509       return (tmp & ip_mask) == ip;
 
  513              !wild_case_compare(system_charset_info, host_arg, hostname)) ||
 
  514             (ip_arg && !wild_compare(ip_arg, hostname, 0)));
 
  543   uint8 
salt[SCRAMBLE_LENGTH + 1];       
 
  549   enum SSL_type ssl_type;
 
  550   const char *ssl_cipher, *x509_issuer, *x509_subject;
 
  553   bool password_expired;
 
  561     dst->user= safe_strdup_root(root, user);
 
  562     dst->ssl_cipher= safe_strdup_root(root, ssl_cipher);
 
  563     dst->x509_issuer= safe_strdup_root(root, x509_issuer);
 
  564     dst->x509_subject= safe_strdup_root(root, x509_subject);
 
  569     if (auth_plugin_is_built_in(dst->plugin.str))
 
  573       dst->plugin.str= strmake_root(root, plugin.str, plugin.length);
 
  574       dst->plugin.length= plugin.length;
 
  576     dst->auth_string.str= safe_strdup_root(root, auth_string.str);
 
  589 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
  590 static void validate_user_plugin_records();
 
  592 static ulong get_sort(uint count,...);
 
  593 static bool show_proxy_grants (THD *thd, 
LEX_USER *user,
 
  594                                char *buff, 
size_t buffsize);
 
  601   const char *proxied_user;
 
  605     MYSQL_PROXIES_PRIV_HOST, 
 
  606     MYSQL_PROXIES_PRIV_USER, 
 
  607     MYSQL_PROXIES_PRIV_PROXIED_HOST,
 
  608     MYSQL_PROXIES_PRIV_PROXIED_USER, 
 
  609     MYSQL_PROXIES_PRIV_WITH_GRANT,
 
  610     MYSQL_PROXIES_PRIV_GRANTOR,
 
  611     MYSQL_PROXIES_PRIV_TIMESTAMP } old_acl_proxy_users;
 
  615   void init(
const char *host_arg, 
const char *user_arg,
 
  616        const char *proxied_host_arg, 
const char *proxied_user_arg,
 
  619     user= (user_arg && *user_arg) ? user_arg : NULL;
 
  621     proxied_user= (proxied_user_arg && *proxied_user_arg) ? 
 
  622       proxied_user_arg : NULL;
 
  623     proxied_host.
update_hostname ((proxied_host_arg && *proxied_host_arg) ?
 
  624                      proxied_host_arg : NULL);
 
  625     with_grant= with_grant_arg;
 
  626     sort= get_sort(4, host.get_host(), user,
 
  627                    proxied_host.get_host(), proxied_user);
 
  630   void init(
MEM_ROOT *mem, 
const char *host_arg, 
const char *user_arg,
 
  631        const char *proxied_host_arg, 
const char *proxied_user_arg,
 
  634     init ((host_arg && *host_arg) ? strdup_root (mem, host_arg) : NULL,
 
  635           (user_arg && *user_arg) ? strdup_root (mem, user_arg) : NULL,
 
  636           (proxied_host_arg && *proxied_host_arg) ? 
 
  637             strdup_root (mem, proxied_host_arg) : NULL,
 
  638           (proxied_user_arg && *proxied_user_arg) ? 
 
  639             strdup_root (mem, proxied_user_arg) : NULL,
 
  645     init (get_field(mem, table->field[MYSQL_PROXIES_PRIV_HOST]),
 
  646           get_field(mem, table->field[MYSQL_PROXIES_PRIV_USER]),
 
  647           get_field(mem, table->field[MYSQL_PROXIES_PRIV_PROXIED_HOST]),
 
  648           get_field(mem, table->field[MYSQL_PROXIES_PRIV_PROXIED_USER]),
 
  649           table->field[MYSQL_PROXIES_PRIV_WITH_GRANT]->val_int() != 0);
 
  652   bool get_with_grant() { 
return with_grant; }
 
  653   const char *get_user() { 
return user; }
 
  654   const char *get_proxied_user() { 
return proxied_user; }
 
  655   const char *get_proxied_host() { 
return proxied_host.get_host(); }
 
  656   void set_user(
MEM_ROOT *mem, 
const char *user_arg) 
 
  658     user= user_arg && *user_arg ? strdup_root(mem, user_arg) : NULL;
 
  661   bool check_validity(
bool check_no_resolve)
 
  663     if (check_no_resolve && 
 
  664         (hostname_requires_resolving(host.get_host()) ||
 
  665          hostname_requires_resolving(proxied_host.get_host())))
 
  667       sql_print_warning(
"'proxies_priv' entry '%s@%s %s@%s' " 
  668                         "ignored in --skip-name-resolve mode.",
 
  669                         proxied_user ? proxied_user : 
"",
 
  670                         proxied_host.get_host() ? proxied_host.get_host() : 
"",
 
  672                         host.get_host() ? host.get_host() : 
"");
 
  678   bool matches(
const char *host_arg, 
const char *user_arg, 
const char *ip_arg,
 
  679                 const char *proxied_user_arg)
 
  681     DBUG_ENTER(
"ACL_PROXY_USER::matches");
 
  682     DBUG_PRINT(
"info", (
"compare_hostname(%s,%s,%s) &&" 
  683                         "compare_hostname(%s,%s,%s) &&" 
  684                         "wild_compare (%s,%s) &&" 
  685                         "wild_compare (%s,%s)",
 
  686                         host.get_host() ? host.get_host() : 
"<NULL>",
 
  687                         host_arg ? host_arg : 
"<NULL>",
 
  688                         ip_arg ? ip_arg : 
"<NULL>",
 
  689                         proxied_host.get_host() ? proxied_host.get_host() : 
"<NULL>",
 
  690                         host_arg ? host_arg : 
"<NULL>",
 
  691                         ip_arg ? ip_arg : 
"<NULL>",
 
  692                         user_arg ? user_arg : 
"<NULL>",
 
  693                         user ? user : 
"<NULL>",
 
  694                         proxied_user_arg ? proxied_user_arg : 
"<NULL>",
 
  695                         proxied_user ? proxied_user : 
"<NULL>"));
 
  696     DBUG_RETURN(host.compare_hostname(host_arg, ip_arg) &&
 
  697                 proxied_host.compare_hostname(host_arg, ip_arg) &&
 
  699                  (user_arg && !wild_compare(user_arg, user, TRUE))) &&
 
  701                  (proxied_user && !wild_compare(proxied_user_arg, 
 
  702                                                 proxied_user, TRUE))));
 
  706   inline static bool auth_element_equals(
const char *a, 
const char *b)
 
  708     return (a == b || (a != NULL && b != NULL && !strcmp(a,b)));
 
  714     DBUG_ENTER(
"pk_equals");
 
  715     DBUG_PRINT(
"info", (
"strcmp(%s,%s) &&" 
  717                         "wild_compare (%s,%s) &&" 
  718                         "wild_compare (%s,%s)",
 
  719                         user ? user : 
"<NULL>",
 
  720                         grant->user ? grant->user : 
"<NULL>",
 
  721                         proxied_user ? proxied_user : 
"<NULL>",
 
  722                         grant->proxied_user ? grant->proxied_user : 
"<NULL>",
 
  723                         host.get_host() ? host.get_host() : 
"<NULL>",
 
  724                         grant->host.get_host() ? grant->host.get_host() : 
"<NULL>",
 
  725                         proxied_host.get_host() ? proxied_host.get_host() : 
"<NULL>",
 
  726                         grant->proxied_host.get_host() ? 
 
  727                         grant->proxied_host.get_host() : 
"<NULL>"));
 
  729     DBUG_RETURN(auth_element_equals(user, grant->user) &&
 
  730                 auth_element_equals(proxied_user, grant->proxied_user) &&
 
  731                 auth_element_equals(host.get_host(), grant->host.get_host()) &&
 
  732                 auth_element_equals(proxied_host.get_host(), 
 
  733                                     grant->proxied_host.get_host()));
 
  737   bool granted_on(
const char *host_arg, 
const char *user_arg)
 
  739     return (((!user && (!user_arg || !user_arg[0])) ||
 
  740              (user && user_arg && !strcmp(user, user_arg))) &&
 
  741             ((!host.get_host() && (!host_arg || !host_arg[0])) ||
 
  742              (host.get_host() && host_arg && !strcmp(host.get_host(), host_arg))));
 
  746   void print_grant(
String *str)
 
  748     str->append(STRING_WITH_LEN(
"GRANT PROXY ON '"));
 
  750       str->append(proxied_user, strlen(proxied_user));
 
  751     str->append(STRING_WITH_LEN(
"'@'"));
 
  752     if (proxied_host.get_host())
 
  753       str->append(proxied_host.get_host(), strlen(proxied_host.get_host()));
 
  754     str->append(STRING_WITH_LEN(
"' TO '"));
 
  756       str->append(user, strlen(user));
 
  757     str->append(STRING_WITH_LEN(
"'@'"));
 
  759       str->append(host.get_host(), strlen(host.get_host()));
 
  760     str->append(STRING_WITH_LEN(
"'"));
 
  762       str->append(STRING_WITH_LEN(
" WITH GRANT OPTION"));
 
  767     with_grant= grant->with_grant;
 
  770   static int store_pk(
TABLE *table, 
 
  776     DBUG_ENTER(
"ACL_PROXY_USER::store_pk");
 
  777     DBUG_PRINT(
"info", (
"host=%s, user=%s, proxied_host=%s, proxied_user=%s",
 
  778                         host->str ? host->str : 
"<NULL>",
 
  779                         user->str ? user->str : 
"<NULL>",
 
  780                         proxied_host->str ? proxied_host->str : 
"<NULL>",
 
  781                         proxied_user->str ? proxied_user->str : 
"<NULL>"));
 
  782     if (table->field[MYSQL_PROXIES_PRIV_HOST]->store(host->str, 
 
  784                                                    system_charset_info))
 
  786     if (table->field[MYSQL_PROXIES_PRIV_USER]->store(user->str, 
 
  788                                                    system_charset_info))
 
  790     if (table->field[MYSQL_PROXIES_PRIV_PROXIED_HOST]->store(proxied_host->str,
 
  791                                                            proxied_host->length,
 
  792                                                            system_charset_info))
 
  794     if (table->field[MYSQL_PROXIES_PRIV_PROXIED_USER]->store(proxied_user->str,
 
  795                                                            proxied_user->length,
 
  796                                                            system_charset_info))
 
  802   static int store_data_record(
TABLE *table,
 
  810     DBUG_ENTER(
"ACL_PROXY_USER::store_pk");
 
  811     if (store_pk(table,  host, user, proxied_host, proxied_user))
 
  813     DBUG_PRINT(
"info", (
"with_grant=%s", with_grant ? 
"TRUE" : 
"FALSE"));
 
  814     if (table->field[MYSQL_PROXIES_PRIV_WITH_GRANT]->store(with_grant ? 1 : 0, 
 
  817     if (table->field[MYSQL_PROXIES_PRIV_GRANTOR]->store(grantor, 
 
  819                                                         system_charset_info))
 
  826 #define FIRST_NON_YN_FIELD 26 
  838                                 my_bool not_used __attribute__((unused)))
 
  840   *length=(uint) entry->length;
 
  841   return (uchar*) entry->key;
 
  844 #define IP_ADDR_STRLEN (3 + 1 + 3 + 1 + 3 + 1 + 3) 
  845 #define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + \ 
  846                         1 + USERNAME_LENGTH + 1) 
  849 #define AUTH_PACKET_HEADER_SIZE_PROTO_41    32 
  850 #define AUTH_PACKET_HEADER_SIZE_PROTO_40    5   
  853 static MEM_ROOT global_acl_memory, memex;
 
  854 static bool initialized=0;
 
  855 static bool allow_all_hosts=1;
 
  856 static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash;
 
  859 static uint grant_version=0; 
 
  860 static ulong get_access(
TABLE *
form,uint fieldnr, uint *next_field=0);
 
  862 static ulong get_sort(uint count,...);
 
  863 static void init_check_host(
void);
 
  864 static void rebuild_check_host(
void);
 
  865 static ACL_USER *find_acl_user(
const char *host, 
const char *user,
 
  867 static bool update_user_table(THD *, 
TABLE *
table, 
const char *host,
 
  869                               const char *new_password,
 
  870                               uint new_password_len,
 
  871                               enum mysql_user_table_field password_field,
 
  872                               bool password_expired, 
bool is_user_table_positioned);
 
  873 static my_bool acl_load(THD *thd, 
TABLE_LIST *tables);
 
  874 static my_bool grant_load(THD *thd, 
TABLE_LIST *tables);
 
  875 static inline void get_grantor(THD *thd, 
char* grantor);
 
  883   COLUMN_PRIVILEGES_HASH,
 
  884   PROC_PRIVILEGES_HASH,
 
  885   FUNC_PRIVILEGES_HASH,
 
  911 set_user_salt(
ACL_USER *acl_user, 
const char *password, uint password_len)
 
  915   if (password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH)
 
  917     get_salt_from_password(acl_user->
salt, password);
 
  918     acl_user->
salt_len= SCRAMBLE_LENGTH;
 
  920   else if (password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
 
  922     get_salt_from_password_323((ulong *) acl_user->
salt, password);
 
  923     acl_user->
salt_len= SCRAMBLE_LENGTH_323;
 
  925   else if (password_len == 0 || password == NULL)
 
  930   else if (acl_user->plugin.str == native_password_plugin_name.str ||
 
  931            acl_user->plugin.str == old_password_plugin_name.str)
 
  941   acl_user->password_expired= 
false;
 
  964 my_bool acl_init(
bool dont_read_acl_tables)
 
  968   DBUG_ENTER(
"acl_init");
 
  970   acl_cache= 
new hash_filo(ACL_CACHE_SIZE, 0, 0,
 
  971                            (my_hash_get_key) acl_entry_get_key,
 
  972                            (my_hash_free_key) free,
 
  973                            &my_charset_utf8_bin);
 
  979   native_password_plugin= my_plugin_lock_by_name(0,
 
  980            &native_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN);
 
  981   old_password_plugin= my_plugin_lock_by_name(0,
 
  982            &old_password_plugin_name, MYSQL_AUTHENTICATION_PLUGIN);
 
  984   if (!native_password_plugin || !old_password_plugin)
 
  987   if (dont_read_acl_tables)
 
  997   thd->thread_stack= (
char*) &thd;
 
  998   thd->store_globals();
 
 1004   return_val= acl_reload(thd);
 
 1007   my_pthread_setspecific_ptr(THR_THD,  0);
 
 1008   DBUG_RETURN(return_val);
 
 1026 static my_bool acl_load(THD *thd, 
TABLE_LIST *tables)
 
 1030   my_bool return_val= TRUE;
 
 1031   bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
 
 1032   char tmp_name[NAME_LEN+1];
 
 1033   int password_length;
 
 1036   sql_mode_t old_sql_mode= thd->variables.sql_mode;
 
 1037   bool password_expired= 
false;
 
 1038   DBUG_ENTER(
"acl_load");
 
 1040   thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
 
 1045   acl_cache->clear(1);                          
 
 1047   init_sql_alloc(&global_acl_memory, ACL_ALLOC_BLOCK_SIZE, 0);
 
 1051   if (init_read_record(&read_record_info, thd, table=tables[0].table,
 
 1054   table->use_all_columns();
 
 1055   (void) my_init_dynamic_array(&acl_users,
sizeof(
ACL_USER),50,100);
 
 1058   while (!(read_record_info.read_record(&read_record_info)))
 
 1060     password_expired= 
false;
 
 1063     memset(&user, 0, 
sizeof(user));
 
 1065                                         table->field[MYSQL_USER_FIELD_HOST]));
 
 1066     user.user= get_field(&global_acl_memory,
 
 1067                          table->field[MYSQL_USER_FIELD_USER]);
 
 1068     if (check_no_resolve && hostname_requires_resolving(user.host.get_host()))
 
 1070       sql_print_warning(
"'user' entry '%s@%s' " 
 1071                         "ignored in --skip-name-resolve mode.",
 
 1072                         user.user ? user.user : 
"",
 
 1073                         user.host.get_host() ? user.host.get_host() : 
"");
 
 1078     password= get_field(&global_acl_memory,
 
 1079                         table->field[MYSQL_USER_FIELD_PASSWORD]);
 
 1080     password_len= password ? strlen(password) : 0;
 
 1081     user.auth_string.str= password ? password : 
const_cast<char*
>(
"");
 
 1082     user.auth_string.length= password_len;
 
 1086       user.access= get_access(table,3,&next_field) & GLOBAL_ACLS;
 
 1091       if (table->s->fields <= 31 && (user.access & CREATE_ACL))
 
 1092         user.access|= (CREATE_VIEW_ACL | SHOW_VIEW_ACL);
 
 1098       if (table->s->fields <= 33 && (user.access & CREATE_ACL))
 
 1099         user.access|= CREATE_PROC_ACL;
 
 1100       if (table->s->fields <= 33 && (user.access & ALTER_ACL))
 
 1101         user.access|= ALTER_PROC_ACL;
 
 1106       if (table->s->fields <= 36 && (user.access & GRANT_ACL))
 
 1107         user.access|= CREATE_USER_ACL;
 
 1114       if (table->s->fields <= 37 && (user.access & SUPER_ACL))
 
 1115         user.access|= EVENT_ACL;
 
 1120       if (table->s->fields <= 38 && (user.access & SUPER_ACL))
 
 1121         user.access|= TRIGGER_ACL;
 
 1123       user.sort= get_sort(2,user.host.get_host(),user.user);
 
 1126       if (table->s->fields >= 31)
 
 1129           get_field(thd->mem_root, table->field[MYSQL_USER_FIELD_SSL_TYPE]);
 
 1131           user.ssl_type=SSL_TYPE_NONE;
 
 1132         else if (!strcmp(ssl_type, 
"ANY"))
 
 1133           user.ssl_type=SSL_TYPE_ANY;
 
 1134         else if (!strcmp(ssl_type, 
"X509"))
 
 1135           user.ssl_type=SSL_TYPE_X509;
 
 1137           user.ssl_type=SSL_TYPE_SPECIFIED;
 
 1140           get_field(&global_acl_memory, table->field[MYSQL_USER_FIELD_SSL_CIPHER]);
 
 1142           get_field(&global_acl_memory, table->field[MYSQL_USER_FIELD_X509_ISSUER]);
 
 1144           get_field(&global_acl_memory, table->field[MYSQL_USER_FIELD_X509_SUBJECT]);
 
 1146         char *ptr= get_field(thd->mem_root,
 
 1147                              table->field[MYSQL_USER_FIELD_MAX_QUESTIONS]);
 
 1148         user.user_resource.questions=ptr ? atoi(ptr) : 0;
 
 1149         ptr= get_field(thd->mem_root,
 
 1150                        table->field[MYSQL_USER_FIELD_MAX_UPDATES]);
 
 1151         user.user_resource.updates=ptr ? atoi(ptr) : 0;
 
 1152         ptr= get_field(thd->mem_root,
 
 1153                        table->field[MYSQL_USER_FIELD_MAX_CONNECTIONS]);
 
 1154         user.user_resource.conn_per_hour= ptr ? atoi(ptr) : 0;
 
 1155         if (user.user_resource.questions || user.user_resource.updates ||
 
 1156             user.user_resource.conn_per_hour)
 
 1159         if (table->s->fields > MYSQL_USER_FIELD_MAX_USER_CONNECTIONS)
 
 1162           ptr= get_field(thd->mem_root,
 
 1163                          table->field[MYSQL_USER_FIELD_MAX_USER_CONNECTIONS]);
 
 1164           user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
 
 1167         if (table->s->fields >= 41)
 
 1170           char *tmpstr= get_field(&global_acl_memory,
 
 1171                                   table->field[MYSQL_USER_FIELD_PLUGIN]);
 
 1178             if (my_strcasecmp(system_charset_info, tmpstr,
 
 1179                               native_password_plugin_name.str) == 0)
 
 1180               user.plugin= native_password_plugin_name;
 
 1182               if (my_strcasecmp(system_charset_info, tmpstr,
 
 1183                                 old_password_plugin_name.str) == 0)
 
 1184                 user.plugin= old_password_plugin_name;
 
 1185 #if defined(HAVE_OPENSSL) 
 1187               if (my_strcasecmp(system_charset_info, tmpstr,
 
 1188                                 sha256_password_plugin_name.str) == 0)
 
 1189                 user.plugin= sha256_password_plugin_name;
 
 1193                 user.plugin.str= tmpstr;
 
 1194                 user.plugin.length= strlen(tmpstr);
 
 1196             if (user.auth_string.length &&
 
 1197                 user.plugin.str != native_password_plugin_name.str &&
 
 1198                 user.plugin.str != old_password_plugin_name.str)
 
 1200               sql_print_warning(
"'user' entry '%s@%s' has both a password " 
 1201                                 "and an authentication plugin specified. The " 
 1202                                 "password will be ignored.",
 
 1203                                 user.user ? user.user : 
"",
 
 1204                                 user.host.get_host() ? user.host.get_host() : 
"");
 
 1206             user.auth_string.str=
 
 1207               get_field(&global_acl_memory,
 
 1208                         table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]);
 
 1209             if (!user.auth_string.str)
 
 1210               user.auth_string.str= 
const_cast<char*
>(
"");
 
 1211             user.auth_string.length= strlen(user.auth_string.str);
 
 1217         if (table->s->fields > MYSQL_USER_FIELD_PASSWORD_EXPIRED)
 
 1219           char *tmpstr= get_field(&global_acl_memory,
 
 1220                                   table->field[MYSQL_USER_FIELD_PASSWORD_EXPIRED]);
 
 1221           if (tmpstr && (*tmpstr == 
'Y' || *tmpstr == 
'y'))
 
 1223             user.password_expired= 
true;
 
 1225             if (!auth_plugin_supports_expiration(user.plugin.str))
 
 1227               sql_print_warning(
"'user' entry '%s@%s' has the password ignore " 
 1228                                 "flag raised, but its authentication plugin " 
 1229                                 "doesn't support password expiration. " 
 1230                                 "The user id will be ignored.",
 
 1231                                 user.user ? user.user : 
"",
 
 1232                                 user.host.get_host() ? user.host.get_host() : 
"");
 
 1235             password_expired= 
true;
 
 1241         user.ssl_type=SSL_TYPE_NONE;
 
 1242 #ifndef TO_BE_REMOVED 
 1243         if (table->s->fields <= 13)
 
 1245           if (user.access & CREATE_ACL)
 
 1246             user.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
 
 1249         user.access|= LOCK_TABLES_ACL | CREATE_TMP_ACL | SHOW_DB_ACL;
 
 1250         if (user.access & FILE_ACL)
 
 1251           user.access|= REPL_CLIENT_ACL | REPL_SLAVE_ACL;
 
 1252         if (user.access & PROCESS_ACL)
 
 1253           user.access|= SUPER_ACL | EXECUTE_ACL;
 
 1256       if (!user.plugin.length)
 
 1264         user.plugin= native_password_plugin_name;
 
 1265         if (password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
 
 1266           user.plugin= old_password_plugin_name;
 
 1272       if (set_user_salt(&user, password, password_len))
 
 1274         sql_print_warning(
"Found invalid password for user: '%s@%s'; " 
 1275                           "Ignoring user", user.user ? user.user : 
"",
 
 1276                           user.host.get_host() ? user.host.get_host() : 
"");
 
 1281       user.password_expired= password_expired;
 
 1283       (void) push_dynamic(&acl_users,(uchar*) &user);
 
 1284       if (user.host.check_allow_all_hosts())
 
 1289   my_qsort((uchar*) dynamic_element(&acl_users,0,
ACL_USER*),acl_users.elements,
 
 1290            sizeof(
ACL_USER),(qsort_cmp) acl_compare);
 
 1291   end_read_record(&read_record_info);
 
 1292   freeze_size(&acl_users);
 
 1296     password_length= table->field[MYSQL_USER_FIELD_PASSWORD]->field_length /
 
 1297       table->field[MYSQL_USER_FIELD_PASSWORD]->charset()->mbmaxlen;
 
 1298     if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
 
 1300       sql_print_error(
"Fatal error: mysql.user table is damaged or in " 
 1301                       "unsupported 3.20 format.");
 
 1305     DBUG_PRINT(
"info",(
"user table fields: %d, password length: %d",
 
 1306                      table->s->fields, password_length));
 
 1309     if (password_length < SCRAMBLED_PASSWORD_CHAR_LENGTH)
 
 1311       if (opt_secure_auth)
 
 1314         sql_print_error(
"Fatal error: mysql.user table is in old format, " 
 1315                         "but server started with --secure-auth option.");
 
 1318       mysql_user_table_is_in_short_password_format= 
true;
 
 1319       if (global_system_variables.old_passwords)
 
 1323         global_system_variables.old_passwords= 1;
 
 1325         sql_print_warning(
"mysql.user table is not updated to new password format; " 
 1326                           "Disabling new password usage until " 
 1327                           "mysql_fix_privilege_tables is run");
 
 1329       thd->variables.old_passwords= 1;
 
 1333       mysql_user_table_is_in_short_password_format= 
false;
 
 1341   if (init_read_record(&read_record_info, thd, table=tables[1].table,
 
 1344   table->use_all_columns();
 
 1345   (void) my_init_dynamic_array(&acl_dbs,
sizeof(
ACL_DB),50,100);
 
 1346   while (!(read_record_info.read_record(&read_record_info)))
 
 1351                             table->field[MYSQL_DB_FIELD_HOST]));
 
 1352     db.db=get_field(&global_acl_memory, table->field[MYSQL_DB_FIELD_DB]);
 
 1355       sql_print_warning(
"Found an entry in the 'db' table with empty database name; Skipped");
 
 1358     db.user=get_field(&global_acl_memory, table->field[MYSQL_DB_FIELD_USER]);
 
 1359     if (check_no_resolve && hostname_requires_resolving(db.host.get_host()))
 
 1361       sql_print_warning(
"'db' entry '%s %s@%s' " 
 1362                         "ignored in --skip-name-resolve mode.",
 
 1364                         db.user ? db.user : 
"",
 
 1365                         db.host.get_host() ? db.host.get_host() : 
"");
 
 1368     db.access=get_access(table,3);
 
 1369     db.access=fix_rights_for_db(db.access);
 
 1370     if (lower_case_table_names)
 
 1376       (void)strmov(tmp_name, db.db);
 
 1377       my_casedn_str(files_charset_info, db.db);
 
 1378       if (strcmp(db.db, tmp_name) != 0)
 
 1380         sql_print_warning(
"'db' entry '%s %s@%s' had database in mixed " 
 1381                           "case that has been forced to lowercase because " 
 1382                           "lower_case_table_names is set. It will not be " 
 1383                           "possible to remove this privilege using REVOKE.",
 
 1385                           db.user ? db.user : 
"",
 
 1386                           db.host.get_host() ? db.host.get_host() : 
"");
 
 1389     db.sort=get_sort(3,db.host.get_host(),db.db,db.user);
 
 1390 #ifndef TO_BE_REMOVED 
 1391     if (table->s->fields <=  9)
 
 1393       if (db.access & CREATE_ACL)
 
 1394         db.access|=REFERENCES_ACL | INDEX_ACL | ALTER_ACL;
 
 1397     (void) push_dynamic(&acl_dbs,(uchar*) &db);
 
 1400   my_qsort((uchar*) dynamic_element(&acl_dbs,0,
ACL_DB*),acl_dbs.elements,
 
 1401            sizeof(
ACL_DB),(qsort_cmp) acl_compare);
 
 1402   end_read_record(&read_record_info);
 
 1403   freeze_size(&acl_dbs);
 
 1406   (void) my_init_dynamic_array(&acl_proxy_users, 
sizeof(
ACL_PROXY_USER), 
 
 1408   if (tables[2].table)
 
 1410     if (init_read_record(&read_record_info, thd, table= tables[2].table,
 
 1413     table->use_all_columns();
 
 1414     while (!(read_record_info.read_record(&read_record_info)))
 
 1418       proxy.init(table, &global_acl_memory);
 
 1419       if (proxy.check_validity(check_no_resolve))
 
 1421       if (push_dynamic(&acl_proxy_users, (uchar*) &proxy))
 
 1423         end_read_record(&read_record_info);
 
 1428     my_qsort((uchar*) dynamic_element(&acl_proxy_users, 0, 
ACL_PROXY_USER*),
 
 1429              acl_proxy_users.elements,
 
 1431     end_read_record(&read_record_info);
 
 1435     sql_print_error(
"Missing system table mysql.proxies_priv; " 
 1436                     "please run mysql_upgrade to create it");
 
 1438   freeze_size(&acl_proxy_users);
 
 1440   validate_user_plugin_records();
 
 1447   thd->variables.sql_mode= old_sql_mode;
 
 1448   DBUG_RETURN(return_val);
 
 1452 void acl_free(
bool end)
 
 1454   free_root(&global_acl_memory,MYF(0));
 
 1455   delete_dynamic(&acl_users);
 
 1456   delete_dynamic(&acl_dbs);
 
 1457   delete_dynamic(&acl_wild_hosts);
 
 1458   delete_dynamic(&acl_proxy_users);
 
 1459   my_hash_free(&acl_check_hosts);
 
 1460   plugin_unlock(0, native_password_plugin);
 
 1461   plugin_unlock(0, old_password_plugin);
 
 1463     acl_cache->clear(1); 
 
 1484 void close_acl_tables(THD *thd)
 
 1487   if (thd->transaction_rollback_request)
 
 1489     trans_rollback_stmt(thd);
 
 1490     trans_rollback_implicit(thd);
 
 1497       trans_commit_stmt(thd);
 
 1498     DBUG_ASSERT(res == 
false);
 
 1517 static bool acl_trans_commit_and_close_tables(THD *thd)
 
 1520   bool rollback= 
false;
 
 1537   DBUG_ASSERT(stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END));
 
 1539   if (thd->transaction_rollback_request)
 
 1545     result= trans_rollback_stmt(thd);
 
 1546     result|= trans_rollback_implicit(thd);
 
 1551     result= trans_commit_stmt(thd);
 
 1552     result|= trans_commit_implicit(thd);
 
 1554   close_thread_tables(thd);
 
 1555   thd->mdl_context.release_transactional_locks();
 
 1557   if (result || rollback)
 
 1563     (void) acl_reload(thd);
 
 1564     (void) grant_reload(thd);
 
 1590 my_bool acl_reload(THD *thd)
 
 1593   DYNAMIC_ARRAY old_acl_users, old_acl_dbs, old_acl_proxy_users;
 
 1595   bool old_initialized;
 
 1596   my_bool return_val= TRUE;
 
 1597   DBUG_ENTER(
"acl_reload");
 
 1604                            C_STRING_WITH_LEN(
"user"), 
"user", TL_READ);
 
 1606                            C_STRING_WITH_LEN(
"db"), 
"db", TL_READ);
 
 1608                            C_STRING_WITH_LEN(
"proxies_priv"), 
 
 1609                            "proxies_priv", TL_READ);
 
 1610   tables[0].next_local= tables[0].next_global= tables + 1;
 
 1611   tables[1].next_local= tables[1].next_global= tables + 2;
 
 1621     if (thd->get_stmt_da()->is_error())
 
 1623       sql_print_error(
"Fatal error: Can't open and lock privilege tables: %s",
 
 1624                       thd->get_stmt_da()->message());
 
 1629   if ((old_initialized=initialized))
 
 1632   old_acl_users= acl_users;
 
 1633   old_acl_proxy_users= acl_proxy_users;
 
 1634   old_acl_dbs= acl_dbs;
 
 1635   old_mem= global_acl_memory;
 
 1636   delete_dynamic(&acl_wild_hosts);
 
 1637   my_hash_free(&acl_check_hosts);
 
 1639   if ((return_val= acl_load(thd, tables)))
 
 1641     DBUG_PRINT(
"error",(
"Reverting to old privileges"));
 
 1643     acl_users= old_acl_users;
 
 1644     acl_proxy_users= old_acl_proxy_users;
 
 1645     acl_dbs= old_acl_dbs;
 
 1646     global_acl_memory= old_mem;
 
 1651     free_root(&old_mem,MYF(0));
 
 1652     delete_dynamic(&old_acl_users);
 
 1653     delete_dynamic(&old_acl_proxy_users);
 
 1654     delete_dynamic(&old_acl_dbs);
 
 1656   if (old_initialized)
 
 1659   close_acl_tables(thd);
 
 1660   DBUG_RETURN(return_val);
 
 1683 static ulong get_access(
TABLE *
form, uint fieldnr, uint *next_field)
 
 1685   ulong access_bits=0,bit;
 
 1687   String res(buff,
sizeof(buff),&my_charset_latin1);
 
 1690   for (pos=form->field+fieldnr, bit=1;
 
 1691        *pos && (*pos)->real_type() == MYSQL_TYPE_ENUM &&
 
 1692          ((
Field_enum*) (*pos))->typelib->count == 2 ;
 
 1693        pos++, fieldnr++, bit<<=1)
 
 1695     (*pos)->val_str(&res);
 
 1696     if (my_toupper(&my_charset_latin1, res[0]) == 
'Y')
 
 1700     *next_field=fieldnr;
 
 1712 static ulong get_sort(uint count,...)
 
 1715   va_start(args,count);
 
 1719   DBUG_ASSERT(count <= 4);
 
 1723     char *start, *str= va_arg(args,
char*);
 
 1729       for (; *str ; str++)
 
 1731         if (*str == wild_prefix && str[1])
 
 1733         else if (*str == wild_many || *str == wild_one)
 
 1735           wild_pos= (uint) (str - start) + 1;
 
 1741     sort= (sort << 8) + (wild_pos ? min(wild_pos, 127
U) : chars);
 
 1750   if (a->sort > b->sort)
 
 1752   if (a->sort < b->sort)
 
 1774 bool acl_getroot(Security_context *sctx, 
char *user, 
char *host,
 
 1780   DBUG_ENTER(
"acl_getroot");
 
 1782   DBUG_PRINT(
"enter", (
"Host: '%s', Ip: '%s', User: '%s', db: '%s'",
 
 1783                        (host ? host : 
"(NULL)"), (ip ? ip : 
"(NULL)"),
 
 1784                        user, (db ? db : 
"(NULL)")));
 
 1786   sctx->set_host(host);
 
 1788   sctx->host_or_ip= host ? host : (ip ? ip : 
"");
 
 1795     sctx->skip_grants();
 
 1801   sctx->master_access= 0;
 
 1803   *sctx->priv_user= *sctx->priv_host= 0;
 
 1811   for (i=0 ; i < acl_users.elements ; i++)
 
 1814     if ((!acl_user_tmp->user && !user[0]) ||
 
 1815         (acl_user_tmp->user && strcmp(user, acl_user_tmp->user) == 0))
 
 1817       if (acl_user_tmp->host.compare_hostname(host, ip))
 
 1819         acl_user= acl_user_tmp;
 
 1828     for (i=0 ; i < acl_dbs.elements ; i++)
 
 1831       if (!acl_db->user ||
 
 1832           (user && user[0] && !strcmp(user, acl_db->user)))
 
 1834         if (acl_db->host.compare_hostname(host, ip))
 
 1836           if (!acl_db->db || (db && !wild_compare(db, acl_db->db, 0)))
 
 1838             sctx->db_access= acl_db->access;
 
 1844     sctx->master_access= acl_user->access;
 
 1847       strmake(sctx->priv_user, user, USERNAME_LENGTH);
 
 1849       *sctx->priv_user= 0;
 
 1851     if (acl_user->host.get_host())
 
 1852       strmake(sctx->priv_host, acl_user->host.get_host(), MAX_HOSTNAME - 1);
 
 1854       *sctx->priv_host= 0;
 
 1856     sctx->password_expired= acl_user->password_expired;
 
 1862 static uchar* check_get_key(
ACL_USER *buff, 
size_t *length,
 
 1863                             my_bool not_used __attribute__((unused)))
 
 1865   *length=buff->host.get_host_len();
 
 1866   return (uchar*) buff->host.get_host();
 
 1870 static void acl_update_user(
const char *user, 
const char *host,
 
 1871                             const char *password, uint password_len,
 
 1872                             enum SSL_type ssl_type,
 
 1873                             const char *ssl_cipher,
 
 1874                             const char *x509_issuer,
 
 1875                             const char *x509_subject,
 
 1881   DBUG_ENTER(
"acl_update_user");
 
 1883   for (uint i=0 ; i < acl_users.elements ; i++)
 
 1886     if ((!acl_user->user && !user[0]) ||
 
 1887         (acl_user->user && !strcmp(user,acl_user->user)))
 
 1889       if ((!acl_user->host.get_host() && !host[0]) ||
 
 1890           (acl_user->host.get_host() &&
 
 1891           !my_strcasecmp(system_charset_info, host, acl_user->host.get_host())))
 
 1893         if (plugin->length > 0)
 
 1895           acl_user->plugin= *plugin;
 
 1896           optimize_plugin_compare_by_pointer(&acl_user->plugin);
 
 1897           if (!auth_plugin_is_built_in(acl_user->plugin.str))
 
 1898             acl_user->plugin.str= strmake_root(&global_acl_memory, plugin->str, plugin->length);
 
 1899           acl_user->auth_string.str= auth->str ?
 
 1900             strmake_root(&global_acl_memory, auth->str,
 
 1901                          auth->length) : const_cast<char*>(
"");
 
 1902           acl_user->auth_string.length= auth->length;
 
 1904         acl_user->access=privileges;
 
 1905         if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
 
 1906           acl_user->user_resource.questions=mqh->questions;
 
 1907         if (mqh->specified_limits & USER_RESOURCES::UPDATES_PER_HOUR)
 
 1908           acl_user->user_resource.updates=mqh->updates;
 
 1909         if (mqh->specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR)
 
 1910           acl_user->user_resource.conn_per_hour= mqh->conn_per_hour;
 
 1911         if (mqh->specified_limits & USER_RESOURCES::USER_CONNECTIONS)
 
 1912           acl_user->user_resource.user_conn= mqh->user_conn;
 
 1913         if (ssl_type != SSL_TYPE_NOT_SPECIFIED)
 
 1915           acl_user->ssl_type= ssl_type;
 
 1916           acl_user->ssl_cipher= (ssl_cipher ? strdup_root(&global_acl_memory,
 
 1918           acl_user->x509_issuer= (x509_issuer ? strdup_root(&global_acl_memory,
 
 1920           acl_user->x509_subject= (x509_subject ?
 
 1921                                    strdup_root(&global_acl_memory, x509_subject) : 0);
 
 1931           int hash_not_ok= set_user_salt(acl_user, password, password_len);
 
 1933           DBUG_ASSERT(hash_not_ok == 0);
 
 1935           password_len+= hash_not_ok;
 
 1946 static void acl_insert_user(
const char *user, 
const char *host,
 
 1947                             const char *password, uint password_len,
 
 1948                             enum SSL_type ssl_type,
 
 1949                             const char *ssl_cipher,
 
 1950                             const char *x509_issuer,
 
 1951                             const char *x509_subject,
 
 1957   DBUG_ENTER(
"acl_insert_user");
 
 1963   acl_user.user= *user ? strdup_root(&global_acl_memory,user) : 0;
 
 1964   acl_user.host.
update_hostname(*host ? strdup_root(&global_acl_memory, host) : 0);
 
 1967     acl_user.plugin= *plugin;
 
 1968     optimize_plugin_compare_by_pointer(&acl_user.plugin);
 
 1969     if (!auth_plugin_is_built_in(acl_user.plugin.str))
 
 1970       acl_user.plugin.str= strmake_root(&global_acl_memory, plugin->str, plugin->length);
 
 1971     acl_user.auth_string.str= auth->str ?
 
 1972       strmake_root(&global_acl_memory, auth->str,
 
 1973                    auth->length) : const_cast<char*>(
"");
 
 1974     acl_user.auth_string.length= auth->length;
 
 1976     optimize_plugin_compare_by_pointer(&acl_user.plugin);
 
 1980     acl_user.plugin= password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 ?
 
 1981       old_password_plugin_name : native_password_plugin_name;
 
 1982     acl_user.auth_string.str= 
const_cast<char*
>(
"");
 
 1983     acl_user.auth_string.length= 0;
 
 1986   acl_user.access= privileges;
 
 1987   acl_user.user_resource= *mqh;
 
 1988   acl_user.sort= get_sort(2,acl_user.host.get_host(), acl_user.user);
 
 1991     (ssl_type != SSL_TYPE_NOT_SPECIFIED ? ssl_type : SSL_TYPE_NONE);
 
 1992   acl_user.ssl_cipher=
 
 1993     ssl_cipher ? strdup_root(&global_acl_memory, ssl_cipher) : 0;
 
 1994   acl_user.x509_issuer=
 
 1995     x509_issuer ? strdup_root(&global_acl_memory, x509_issuer) : 0;
 
 1996   acl_user.x509_subject=
 
 1997     x509_subject ? strdup_root(&global_acl_memory, x509_subject) : 0;
 
 1999   hash_not_ok= set_user_salt(&acl_user, password, password_len);
 
 2000   DBUG_ASSERT(hash_not_ok == 0);
 
 2002   password_len+= hash_not_ok;
 
 2005   (void) push_dynamic(&acl_users,(uchar*) &acl_user);
 
 2006   if (acl_user.host.check_allow_all_hosts())
 
 2008   my_qsort((uchar*) dynamic_element(&acl_users,0,
ACL_USER*),acl_users.elements,
 
 2009            sizeof(
ACL_USER),(qsort_cmp) acl_compare);
 
 2012   rebuild_check_host();
 
 2017 static void acl_update_db(
const char *user, 
const char *host, 
const char *db,
 
 2022   for (uint i=0 ; i < acl_dbs.elements ; i++)
 
 2025     if ((!acl_db->user && !user[0]) ||
 
 2027         !strcmp(user,acl_db->user)))
 
 2029       if ((!acl_db->host.get_host() && !host[0]) ||
 
 2030           (acl_db->host.get_host() &&
 
 2031           !strcmp(host, acl_db->host.get_host())))
 
 2033         if ((!acl_db->db && !db[0]) ||
 
 2034             (acl_db->db && !strcmp(db,acl_db->db)))
 
 2037             acl_db->access=privileges;
 
 2039             delete_dynamic_element(&acl_dbs,i);
 
 2061 static void acl_insert_db(
const char *user, 
const char *host, 
const char *db,
 
 2066   acl_db.user= strdup_root(&global_acl_memory,user);
 
 2067   acl_db.host.
update_hostname(*host ? strdup_root(&global_acl_memory, host) : 0);
 
 2068   acl_db.db= strdup_root(&global_acl_memory, db);
 
 2069   acl_db.access= privileges;
 
 2070   acl_db.sort= get_sort(3,acl_db.host.get_host(), acl_db.db, acl_db.user);
 
 2071   (void) push_dynamic(&acl_dbs, (uchar*) &acl_db);
 
 2072   my_qsort((uchar*) dynamic_element(&acl_dbs, 0, 
ACL_DB*), acl_dbs.elements,
 
 2073                  sizeof(
ACL_DB),(qsort_cmp) acl_compare);
 
 2085 ulong acl_get(
const char *host, 
const char *ip,
 
 2086               const char *user, 
const char *db, my_bool db_is_pattern)
 
 2088   ulong host_access= ~(ulong)0, db_access= 0;
 
 2090   size_t key_length, copy_length;
 
 2091   char key[ACL_KEY_LENGTH],*tmp_db,*end;
 
 2093   DBUG_ENTER(
"acl_get");
 
 2095   copy_length= (size_t) (strlen(ip ? ip : 
"") +
 
 2096                  strlen(user ? user : 
"") +
 
 2097                  strlen(db ? db : 
""));
 
 2101   if (copy_length >= ACL_KEY_LENGTH)
 
 2105   end=strmov((tmp_db=strmov(strmov(key, ip ? ip : 
"")+1,user)+1),db);
 
 2106   if (lower_case_table_names)
 
 2108     my_casedn_str(files_charset_info, tmp_db);
 
 2111   key_length= (size_t) (end-key);
 
 2112   if (!db_is_pattern && (entry=(
acl_entry*) acl_cache->search((uchar*) key,
 
 2115     db_access=entry->access;
 
 2117     DBUG_PRINT(
"exit", (
"access: 0x%lx", db_access));
 
 2118     DBUG_RETURN(db_access);
 
 2124   for (i=0 ; i < acl_dbs.elements ; i++)
 
 2127     if (!acl_db->user || !strcmp(user,acl_db->user))
 
 2129       if (acl_db->host.compare_hostname(host,ip))
 
 2131         if (!acl_db->db || !wild_compare(db,acl_db->db,db_is_pattern))
 
 2133           db_access=acl_db->access;
 
 2134           if (acl_db->host.get_host())
 
 2146   if (!db_is_pattern &&
 
 2149     entry->access=(db_access & host_access);
 
 2150     entry->length=key_length;
 
 2151     memcpy((uchar*) entry->key,key,key_length);
 
 2152     acl_cache->add(entry);
 
 2155   DBUG_PRINT(
"exit", (
"access: 0x%lx", db_access & host_access));
 
 2156   DBUG_RETURN(db_access & host_access);
 
 2167 static void init_check_host(
void)
 
 2169   DBUG_ENTER(
"init_check_host");
 
 2170   (void) my_init_dynamic_array(&acl_wild_hosts,
sizeof(
class ACL_HOST_AND_IP),
 
 2171                           acl_users.elements,1);
 
 2172   (void) my_hash_init(&acl_check_hosts,system_charset_info,
 
 2173                       acl_users.elements, 0, 0,
 
 2174                       (my_hash_get_key) check_get_key, 0, 0);
 
 2175   if (!allow_all_hosts)
 
 2177     for (uint i=0 ; i < acl_users.elements ; i++)
 
 2180       if (acl_user->host.has_wildcard())
 
 2183         for (j=0 ; j < acl_wild_hosts.elements ; j++)
 
 2187           if (!my_strcasecmp(system_charset_info,
 
 2188                              acl_user->host.get_host(), acl->get_host()))
 
 2191         if (j == acl_wild_hosts.elements)       
 
 2192           (void) push_dynamic(&acl_wild_hosts,(uchar*) &acl_user->host);
 
 2194       else if (!my_hash_search(&acl_check_hosts,(uchar*)
 
 2195                                acl_user->host.get_host(),
 
 2196                                strlen(acl_user->host.get_host())))
 
 2198         if (my_hash_insert(&acl_check_hosts,(uchar*) acl_user))
 
 2206   freeze_size(&acl_wild_hosts);
 
 2207   freeze_size(&acl_check_hosts.array);
 
 2220 void rebuild_check_host(
void)
 
 2222   delete_dynamic(&acl_wild_hosts);
 
 2223   my_hash_free(&acl_check_hosts);
 
 2230 bool acl_check_host(
const char *host, 
const char *ip)
 
 2232   if (allow_all_hosts)
 
 2236   if ((host && my_hash_search(&acl_check_hosts,(uchar*) host,strlen(host))) ||
 
 2237       (ip && my_hash_search(&acl_check_hosts,(uchar*) ip, strlen(ip))))
 
 2242   for (uint i=0 ; i < acl_wild_hosts.elements ; i++)
 
 2245     if (acl->compare_hostname(host, ip))
 
 2257     inc_host_errors(ip, &errors);
 
 2278 int check_change_password(THD *thd, 
const char *host, 
const char *user,
 
 2279                            char *new_password, uint new_password_len)
 
 2283     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--skip-grant-tables");
 
 2286   if (!thd->slave_thread &&
 
 2287       (strcmp(thd->security_ctx->user, user) ||
 
 2288        my_strcasecmp(system_charset_info, host,
 
 2289                      thd->security_ctx->priv_host)))
 
 2291     if (
check_access(thd, UPDATE_ACL, 
"mysql", NULL, NULL, 1, 0))
 
 2294   if (!thd->slave_thread && !thd->security_ctx->user[0])
 
 2296     my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER),
 
 2320 update_sctx_cache(Security_context *sctx, 
ACL_USER *acl_user_ptr, 
bool expired)
 
 2322   const char *acl_host= acl_user_ptr->host.get_host();
 
 2323   const char *acl_user= acl_user_ptr->user;
 
 2324   const char *sctx_user= sctx->priv_user;
 
 2325   const char *sctx_host= sctx->priv_host;
 
 2336   if (!strcmp(acl_user, sctx_user) && !strcmp(acl_host, sctx_host))
 
 2338     sctx->password_expired= expired;
 
 2368 bool change_password(THD *thd, 
const char *host, 
const char *user,
 
 2376   bool save_binlog_row_based;
 
 2377   uchar user_key[MAX_KEY_LENGTH];
 
 2378   char *plugin_temp= NULL;
 
 2380   uint new_password_len= (uint) strlen(new_password);
 
 2382   enum mysql_user_table_field password_field= MYSQL_USER_FIELD_PASSWORD;
 
 2383   DBUG_ENTER(
"change_password");
 
 2384   DBUG_PRINT(
"enter",(
"host: '%s'  user: '%s'  new_password: '%s'",
 
 2385                       host,user,new_password));
 
 2386   DBUG_ASSERT(host != 0);                       
 
 2388   if (check_change_password(thd, host, user, new_password, new_password_len))
 
 2393 #ifdef HAVE_REPLICATION 
 2398   if (thd->slave_thread && rpl_filter->is_on())
 
 2406     if (!(thd->sp_runtime_ctx || rpl_filter->tables_ok(0, &tables)))
 
 2410   if (!(table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
 
 2413   if (!table->key_info)
 
 2415     my_error(ER_TABLE_CORRUPT, MYF(0), table->s->db.str,
 
 2416              table->s->table_name.str);
 
 2425   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 2426     thd->clear_current_stmt_binlog_format_row();
 
 2430   if (!(acl_user= find_acl_user(host, user, TRUE)))
 
 2433     my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0));
 
 2437   table->use_all_columns();
 
 2438   DBUG_ASSERT(host != 
'\0');
 
 2439   table->field[MYSQL_USER_FIELD_HOST]->store(host, strlen(host),
 
 2440                                              system_charset_info);
 
 2441   table->field[MYSQL_USER_FIELD_USER]->store(user, strlen(user),
 
 2442                                              system_charset_info);
 
 2444   key_copy((uchar *) user_key, table->record[0], table->key_info,
 
 2449     plugin_temp= (table->s->fields > MYSQL_USER_FIELD_PLUGIN) ?
 
 2450                  get_field(&global_acl_memory, table->field[MYSQL_USER_FIELD_PLUGIN]) : NULL;
 
 2454   plugin_empty= plugin_temp ? 
false: 
true;
 
 2456   if (acl_user->plugin.length == 0)
 
 2458     acl_user->plugin.length= default_auth_plugin_name.length;
 
 2459     acl_user->plugin.str= default_auth_plugin_name.str;
 
 2462   if (new_password_len == 0)
 
 2464     String *password_str= 
new (thd->mem_root) 
String(new_password,
 
 2466                                                      character_set_client);
 
 2467     if (check_password_policy(password_str))
 
 2475 #if defined(HAVE_OPENSSL) 
 2481   if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
 
 2482                     sha256_password_plugin_name.str) == 0)
 
 2487     if (new_password_len == 0)
 
 2488       acl_user->auth_string= empty_lex_str;
 
 2492     else if (new_password[0] == 
'$' &&
 
 2493              new_password[1] == 
'5' &&
 
 2494              new_password[2] == 
'$')
 
 2496       password_field= MYSQL_USER_FIELD_AUTHENTICATION_STRING;
 
 2497       if (new_password_len < CRYPT_MAX_PASSWORD_SIZE + 1)
 
 2503         if (!update_sctx_cache(thd->security_ctx, acl_user, 
false) &&
 
 2504             thd->security_ctx->password_expired)
 
 2507           my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
 
 2513         acl_user->password_expired= 
false;
 
 2515         acl_user->auth_string.str= (
char *) memdup_root(&global_acl_memory,
 
 2517                                                        new_password_len + 1);
 
 2518         acl_user->auth_string.length= new_password_len;
 
 2526       my_error(ER_PASSWORD_FORMAT, MYF(0));
 
 2534   if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
 
 2535                     native_password_plugin_name.str) == 0 ||
 
 2536       my_strcasecmp(system_charset_info, acl_user->plugin.str,
 
 2537                     old_password_plugin_name.str) == 0)
 
 2539     password_field= MYSQL_USER_FIELD_PASSWORD;
 
 2545     if (new_password_len != 0)
 
 2549         if (new_password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH)
 
 2550           acl_user->plugin= native_password_plugin_name;
 
 2551         else if (new_password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
 
 2552           acl_user->plugin= old_password_plugin_name;
 
 2555           my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
 
 2563         if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
 
 2564                           native_password_plugin_name.str) == 0 &&
 
 2565             new_password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH)
 
 2567           my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH);
 
 2572         else if (my_strcasecmp(system_charset_info, acl_user->plugin.str,
 
 2573                                old_password_plugin_name.str) == 0 &&
 
 2574                  new_password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
 
 2576           my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH_323);
 
 2583     else if (plugin_empty)
 
 2584       acl_user->plugin= native_password_plugin_name;
 
 2593     if (set_user_salt(acl_user, new_password, new_password_len))
 
 2595       my_error(ER_PASSWORD_FORMAT, MYF(0));
 
 2600     if (!update_sctx_cache(thd->security_ctx, acl_user, 
false) &&
 
 2601         thd->security_ctx->password_expired)
 
 2603       my_error(ER_MUST_CHANGE_PASSWORD, MYF(0));
 
 2611      push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
 
 2612                   ER_SET_PASSWORD_AUTH_PLUGIN, ER(ER_SET_PASSWORD_AUTH_PLUGIN));
 
 2617      new_password_len= 0;
 
 2620   if (update_user_table(thd, table,
 
 2621                         acl_user->host.get_host() ? acl_user->host.get_host() : 
"",
 
 2622                         acl_user->user ? acl_user->user : 
"",
 
 2623                         new_password, new_password_len, password_field, 
false, 
true))
 
 2629   acl_cache->clear(1);                          
 
 2632   query_length= sprintf(buff, 
"SET PASSWORD FOR '%-.120s'@'%-.120s'='%-.120s'",
 
 2633                         acl_user->user ? acl_user->user : 
"",
 
 2634                         acl_user->host.get_host() ? acl_user->host.get_host() : 
"",
 
 2636   result= write_bin_log(thd, 
true, buff, query_length,
 
 2637                         table->file->has_transactions());
 
 2639   result|= acl_trans_commit_and_close_tables(thd);
 
 2642   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 2643   if (save_binlog_row_based)
 
 2644     thd->set_current_stmt_binlog_format_row();
 
 2646   DBUG_RETURN(result);
 
 2663 bool is_acl_user(
const char *host, 
const char *user)
 
 2672   res= find_acl_user(host, user, TRUE) != NULL;
 
 2683 find_acl_user(
const char *host, 
const char *user, my_bool exact)
 
 2685   DBUG_ENTER(
"find_acl_user");
 
 2686   DBUG_PRINT(
"enter",(
"host: '%s'  user: '%s'",host,user));
 
 2690   for (uint i=0 ; i < acl_users.elements ; i++)
 
 2693     DBUG_PRINT(
"info",(
"strcmp('%s','%s'), compare_hostname('%s','%s'),",
 
 2694                        user, acl_user->user ? acl_user->user : 
"",
 
 2696                        acl_user->host.get_host() ? acl_user->host.get_host() :
 
 2698     if ((!acl_user->user && !user[0]) ||
 
 2699         (acl_user->user && !strcmp(user,acl_user->user)))
 
 2701       if (exact ? !my_strcasecmp(system_charset_info, host,
 
 2702                                  acl_user->host.get_host() ?
 
 2703                                  acl_user->host.get_host() : 
"") :
 
 2704           acl_user->host.compare_hostname(host,host))
 
 2706         DBUG_RETURN(acl_user);
 
 2739 bool hostname_requires_resolving(
const char *hostname)
 
 2746   size_t hostname_len= strlen(hostname);
 
 2747   size_t localhost_len= strlen(my_localhost);
 
 2749   if (hostname == my_localhost ||
 
 2750       (hostname_len == localhost_len &&
 
 2751        !my_strnncoll(system_charset_info,
 
 2752                      (
const uchar *) hostname,  hostname_len,
 
 2753                      (
const uchar *) my_localhost, strlen(my_localhost))))
 
 2766   for (
const char *p= hostname; *p; ++p)
 
 2783   for (
const char *p= hostname; *p; ++p)
 
 2785     if (*p != 
'.' && !my_isdigit(&my_charset_latin1, *p))
 
 2809 update_user_table(THD *thd, 
TABLE *table,
 
 2810                   const char *host, 
const char *user,
 
 2811                   const char *new_password, uint new_password_len,
 
 2812                   enum mysql_user_table_field password_field,
 
 2813                   bool password_expired, 
bool is_user_table_positioned)
 
 2815   char user_key[MAX_KEY_LENGTH];
 
 2817   DBUG_ENTER(
"update_user_table");
 
 2818   DBUG_PRINT(
"enter",(
"user: %s  host: %s",user,host));
 
 2821   if (table->s->fields <= MYSQL_USER_FIELD_PASSWORD_EXPIRED &&
 
 2824     my_error(ER_BAD_FIELD_ERROR, MYF(0), 
"password_expired", 
"mysql.user");
 
 2833   if (!is_user_table_positioned)
 
 2835     table->use_all_columns();
 
 2836     DBUG_ASSERT(host != 
'\0');
 
 2837     table->field[MYSQL_USER_FIELD_HOST]->store(host, (uint) strlen(host),
 
 2838                                                system_charset_info);
 
 2839     table->field[MYSQL_USER_FIELD_USER]->store(user, (uint) strlen(user),
 
 2840                                                system_charset_info);
 
 2841     key_copy((uchar *) user_key, table->record[0], table->key_info,
 
 2845                                            (uchar *) user_key, HA_WHOLE_KEY,
 
 2848       my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH),
 
 2853   store_record(table,
record[1]);
 
 2859   if (!password_expired)
 
 2861     table->field[(int) password_field]->store(new_password, new_password_len,
 
 2862                                               system_charset_info);
 
 2863     if (new_password_len == SCRAMBLED_PASSWORD_CHAR_LENGTH_323 &&
 
 2864         password_field == MYSQL_USER_FIELD_PASSWORD)
 
 2866       WARN_DEPRECATED_41_PWD_HASH(thd);
 
 2870   if (table->s->fields > MYSQL_USER_FIELD_PASSWORD_EXPIRED)
 
 2873     table->field[MYSQL_USER_FIELD_PASSWORD_EXPIRED]->store(password_expired ?
 
 2875                                                            system_charset_info);
 
 2878   if ((error=table->file->ha_update_row(table->record[1],table->record[0])) &&
 
 2879        error != HA_ERR_RECORD_IS_THE_SAME)
 
 2896 static bool test_if_create_new_users(THD *thd)
 
 2898   Security_context *sctx= thd->security_ctx;
 
 2899   bool create_new_users= 
test(sctx->master_access & INSERT_ACL) ||
 
 2900                          (!opt_safe_user_create &&
 
 2901                           test(sctx->master_access & CREATE_USER_ACL));
 
 2902   if (!create_new_users)
 
 2907                       C_STRING_WITH_LEN(
"user"), 
"user", TL_WRITE);
 
 2908     create_new_users= 1;
 
 2910     db_access=acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
 
 2911                       sctx->priv_user, tl.db, 0);
 
 2912     if (!(db_access & INSERT_ACL))
 
 2914       if (check_grant(thd, INSERT_ACL, &tl, FALSE, UINT_MAX, TRUE))
 
 2918   return create_new_users;
 
 2931 bool auth_plugin_supports_expiration(
const char *plugin_name)
 
 2933  return (!plugin_name || !*plugin_name ||
 
 2934          plugin_name == native_password_plugin_name.str ||
 
 2935 #
if defined(HAVE_OPENSSL)
 
 2936          plugin_name == sha256_password_plugin_name.str ||
 
 2938          plugin_name == old_password_plugin_name.str);
 
 2946 static int replace_user_table(THD *thd, 
TABLE *table, 
LEX_USER *combo,
 
 2947                               ulong rights, 
bool revoke_grant,
 
 2948                               bool can_create_user, 
bool no_auto_create)
 
 2951   bool old_row_exists=0;
 
 2952   char *password= empty_c_string;
 
 2953   uint password_len= 0;
 
 2954   char what= (revoke_grant) ? 
'N' : 
'Y';
 
 2955   uchar user_key[MAX_KEY_LENGTH];
 
 2957   DBUG_ENTER(
"replace_user_table");
 
 2961   if (!table->key_info)
 
 2963     my_error(ER_TABLE_CORRUPT, MYF(0), table->s->db.str,
 
 2964              table->s->table_name.str);
 
 2968   table->use_all_columns();
 
 2969   DBUG_ASSERT(combo->host.str != 
'\0');
 
 2970   table->field[MYSQL_USER_FIELD_HOST]->store(combo->host.str,combo->host.length,
 
 2971                                              system_charset_info);
 
 2972   table->field[MYSQL_USER_FIELD_USER]->store(combo->user.str,combo->user.length,
 
 2973                                              system_charset_info);
 
 2974   key_copy(user_key, table->record[0], table->key_info,
 
 2987       my_error(ER_NONEXISTING_GRANT, MYF(0), combo->user.str, combo->host.str);
 
 2992     if (!combo->uses_identified_with_clause)
 
 2994       combo->plugin.str= default_auth_plugin_name.str;
 
 2995       combo->plugin.length= default_auth_plugin_name.length;
 
 2998     if (combo->uses_identified_by_clause)
 
 3000       if (digest_password(thd, combo))
 
 3002         my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), CRYPT_MAX_PASSWORD_SIZE);
 
 3007     password= combo->password.str;
 
 3008     password_len= combo->password.length;
 
 3022     if (!password_len &&
 
 3023         auth_plugin_is_built_in(combo->plugin.str) && 
 
 3026       my_error(ER_PASSWORD_NO_MATCH, MYF(0), combo->user.str, combo->host.str);
 
 3029     else if (!can_create_user)
 
 3031       my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0));
 
 3034     else if (combo->plugin.str[0])
 
 3036       if (!plugin_is_ready(&combo->plugin, MYSQL_AUTHENTICATION_PLUGIN))
 
 3038         my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), combo->plugin.str);
 
 3044     restore_record(table,s->default_values);
 
 3045     DBUG_ASSERT(combo->host.str != 
'\0');
 
 3046     table->field[MYSQL_USER_FIELD_HOST]->store(combo->host.str,combo->host.length,
 
 3047                                                system_charset_info);
 
 3048     table->field[MYSQL_USER_FIELD_USER]->store(combo->user.str,combo->user.length,
 
 3049                                                system_charset_info);
 
 3050 #if defined(HAVE_OPENSSL) 
 3051     if (combo->plugin.str == sha256_password_plugin_name.str)
 
 3054       combo->auth.str= password;
 
 3055       combo->auth.length= password_len;
 
 3056       if (password_len > 0)
 
 3058           field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->
 
 3059             store(password, password_len, &my_charset_utf8_bin);
 
 3062         field[MYSQL_USER_FIELD_PLUGIN]->
 
 3063           store(sha256_password_plugin_name.str,
 
 3064                 sha256_password_plugin_name.length,
 
 3065                 system_charset_info);
 
 3072       table->field[MYSQL_USER_FIELD_PASSWORD]->store(password, password_len,
 
 3073                                                      system_charset_info);
 
 3074       table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->store(
"\0", 0,
 
 3075                                                      &my_charset_utf8_bin);
 
 3085     store_record(table,
record[1]);                      
 
 3092     if (combo->uses_identified_with_clause)
 
 3095       my_error(ER_GRANT_PLUGIN_USER_EXISTS, MYF(0), combo->user.length,
 
 3108       get_field(thd->mem_root, table->field[MYSQL_USER_FIELD_PLUGIN]);
 
 3116       old_plugin.length= strlen(old_plugin.str);
 
 3122       optimize_plugin_compare_by_pointer(&old_plugin);
 
 3130       if ((combo->uses_identified_by_clause ||
 
 3131            combo->uses_identified_by_password_clause) &&
 
 3132           !auth_plugin_is_built_in(old_plugin.str))
 
 3134         const char *new_plugin= (combo->plugin.str && combo->plugin.str[0]) ?
 
 3135           combo->plugin.str : default_auth_plugin_name.str;
 
 3137         if (my_strcasecmp(system_charset_info, new_plugin, old_plugin.str))
 
 3139           push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 
 
 3140             ER_SET_PASSWORD_AUTH_PLUGIN, ER(ER_SET_PASSWORD_AUTH_PLUGIN));
 
 3144     old_plugin.length= 0;
 
 3145     combo->plugin= old_plugin;
 
 3165     if (combo->plugin.str == NULL || combo->plugin.str == 
'\0')
 
 3167       if (combo->uses_identified_by_password_clause)
 
 3169         if ((combo->password.length == SCRAMBLED_PASSWORD_CHAR_LENGTH) ||
 
 3170             (combo->password.length == 0))
 
 3172           combo->plugin.str= native_password_plugin_name.str;
 
 3173           combo->plugin.length= native_password_plugin_name.length;
 
 3175         else if (combo->password.length == SCRAMBLED_PASSWORD_CHAR_LENGTH_323)
 
 3177           combo->plugin.str= old_password_plugin_name.str;
 
 3178           combo->plugin.length= old_password_plugin_name.length;
 
 3186           my_error(ER_PASSWORD_FORMAT, MYF(0));
 
 3198         if ((thd->variables.old_passwords == 1) && (combo->password.length != 0))
 
 3200           combo->plugin.str= old_password_plugin_name.str;
 
 3201           combo->plugin.length= old_password_plugin_name.length;
 
 3203         else if ((thd->variables.old_passwords == 0) || 
 
 3204                  (combo->password.length == 0))
 
 3206           combo->plugin.str= native_password_plugin_name.str;
 
 3207           combo->plugin.length= native_password_plugin_name.length;
 
 3212           my_error(ER_PASSWORD_FORMAT, MYF(0));
 
 3219     if (!combo->uses_authentication_string_clause)
 
 3221       combo->auth.str= get_field(thd->mem_root,
 
 3222         table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]);
 
 3223       if (combo->auth.str)
 
 3224         combo->auth.length= strlen(combo->auth.str);
 
 3226         combo->auth.length= 0;
 
 3230     if (combo->uses_identified_by_clause)
 
 3232       if (digest_password(thd, combo))
 
 3238     password= combo->password.str;
 
 3239     password_len= combo->password.length;
 
 3241     if (password_len > 0)
 
 3243 #if defined(HAVE_OPENSSL) 
 3244       if (combo->plugin.str == sha256_password_plugin_name.str)
 
 3246         table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->
 
 3247           store(password, password_len, &my_charset_utf8_bin);
 
 3248         combo->auth.str= password;
 
 3249         combo->auth.length= password_len;
 
 3254         table->field[MYSQL_USER_FIELD_PASSWORD]->
 
 3255           store(password, password_len, system_charset_info);
 
 3256         table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->
 
 3257           store(
"\0", 0, &my_charset_utf8_bin);
 
 3260     else if (!rights && !revoke_grant &&
 
 3261              lex->ssl_type == SSL_TYPE_NOT_SPECIFIED &&
 
 3262              !lex->mqh.specified_limits)
 
 3265       DBUG_PRINT(
"info", (
"Proxy user exit path"));
 
 3271   if (password_len > 0)
 
 3278     if ((combo->plugin.str == native_password_plugin_name.str &&
 
 3279          password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH) ||
 
 3280         (combo->plugin.str == old_password_plugin_name.str &&
 
 3281          password_len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323))
 
 3283       my_error(ER_PASSWORD_FORMAT, MYF(0));
 
 3288     if (combo->plugin.str == old_password_plugin_name.str)
 
 3289       WARN_DEPRECATED_41_PWD_HASH(thd);
 
 3297   for (tmp_field= table->field+3, priv = SELECT_ACL;
 
 3298        *tmp_field && (*tmp_field)->real_type() == MYSQL_TYPE_ENUM &&
 
 3299          ((
Field_enum*) (*tmp_field))->typelib->count == 2 ;
 
 3300        tmp_field++, priv <<= 1)
 
 3303       (*tmp_field)->store(&what, 1, &my_charset_latin1);
 
 3305   rights= get_access(table, 3, &next_field);
 
 3306   DBUG_PRINT(
"info",(
"table fields: %d",table->s->fields));
 
 3307   if (table->s->fields >= 31)           
 
 3310     switch (lex->ssl_type) {
 
 3312       table->field[MYSQL_USER_FIELD_SSL_TYPE]->store(STRING_WITH_LEN(
"ANY"),
 
 3313                                       &my_charset_latin1);
 
 3314       table->field[MYSQL_USER_FIELD_SSL_CIPHER]->
 
 3315         store(
"", 0, &my_charset_latin1);
 
 3316       table->field[MYSQL_USER_FIELD_X509_ISSUER]->store(
"", 0, &my_charset_latin1);
 
 3317       table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store(
"", 0, &my_charset_latin1);
 
 3320       table->field[MYSQL_USER_FIELD_SSL_TYPE]->store(STRING_WITH_LEN(
"X509"),
 
 3321                                       &my_charset_latin1);
 
 3322       table->field[MYSQL_USER_FIELD_SSL_CIPHER]->
 
 3323         store(
"", 0, &my_charset_latin1);
 
 3324       table->field[MYSQL_USER_FIELD_X509_ISSUER]->store(
"", 0, &my_charset_latin1);
 
 3325       table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store(
"", 0, &my_charset_latin1);
 
 3327     case SSL_TYPE_SPECIFIED:
 
 3328       table->field[MYSQL_USER_FIELD_SSL_TYPE]->store(STRING_WITH_LEN(
"SPECIFIED"),
 
 3329                                       &my_charset_latin1);
 
 3330       table->field[MYSQL_USER_FIELD_SSL_CIPHER]->store(
"", 0, &my_charset_latin1);
 
 3331       table->field[MYSQL_USER_FIELD_X509_ISSUER]->store(
"", 0, &my_charset_latin1);
 
 3332       table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store(
"", 0, &my_charset_latin1);
 
 3333       if (lex->ssl_cipher)
 
 3334         table->field[MYSQL_USER_FIELD_SSL_CIPHER]->store(lex->ssl_cipher,
 
 3335                                 strlen(lex->ssl_cipher), system_charset_info);
 
 3336       if (lex->x509_issuer)
 
 3337         table->field[MYSQL_USER_FIELD_X509_ISSUER]->store(lex->x509_issuer,
 
 3338                                 strlen(lex->x509_issuer), system_charset_info);
 
 3339       if (lex->x509_subject)
 
 3340         table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store(lex->x509_subject,
 
 3341                                 strlen(lex->x509_subject), system_charset_info);
 
 3343     case SSL_TYPE_NOT_SPECIFIED:
 
 3346       table->field[MYSQL_USER_FIELD_SSL_TYPE]->store(
"", 0, &my_charset_latin1);
 
 3347       table->field[MYSQL_USER_FIELD_SSL_CIPHER]->store(
"", 0, &my_charset_latin1);
 
 3348       table->field[MYSQL_USER_FIELD_X509_ISSUER]->store(
"", 0, &my_charset_latin1);
 
 3349       table->field[MYSQL_USER_FIELD_X509_SUBJECT]->store(
"", 0, &my_charset_latin1);
 
 3355     if (mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
 
 3356       table->field[MYSQL_USER_FIELD_MAX_QUESTIONS]->
 
 3357         store((longlong) mqh.questions, TRUE);
 
 3358     if (mqh.specified_limits & USER_RESOURCES::UPDATES_PER_HOUR)
 
 3359       table->field[MYSQL_USER_FIELD_MAX_UPDATES]->
 
 3360         store((longlong) mqh.updates, TRUE);
 
 3361     if (mqh.specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR)
 
 3362       table->field[MYSQL_USER_FIELD_MAX_CONNECTIONS]->
 
 3363         store((longlong) mqh.conn_per_hour, TRUE);
 
 3364     if (table->s->fields >= 36 &&
 
 3365         (mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
 
 3366       table->field[MYSQL_USER_FIELD_MAX_USER_CONNECTIONS]->
 
 3367         store((longlong) mqh.user_conn, TRUE);
 
 3368     mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
 
 3371     if (combo->plugin.length > 0 && !old_row_exists)
 
 3373       if (table->s->fields >= 41)
 
 3375         table->field[MYSQL_USER_FIELD_PLUGIN]->
 
 3376           store(combo->plugin.str, combo->plugin.length, system_charset_info);
 
 3377         table->field[MYSQL_USER_FIELD_PLUGIN]->set_notnull();
 
 3378         table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->
 
 3379           store(combo->auth.str, combo->auth.length, &my_charset_utf8_bin);
 
 3380         table->field[MYSQL_USER_FIELD_AUTHENTICATION_STRING]->set_notnull();
 
 3384         my_error(ER_BAD_FIELD_ERROR, MYF(0), 
"plugin", 
"mysql.user");
 
 3390     if (table->s->fields > MYSQL_USER_FIELD_PASSWORD_EXPIRED &&
 
 3392       table->field[MYSQL_USER_FIELD_PASSWORD_EXPIRED]->store(
"N", 1,
 
 3393                                                              system_charset_info);
 
 3402     if (cmp_record(table,
record[1]))
 
 3405            table->file->ha_update_row(table->record[1],table->record[0])) &&
 
 3406           error != HA_ERR_RECORD_IS_THE_SAME)
 
 3416   else if ((error=table->file->ha_write_row(table->record[0]))) 
 
 3430     acl_cache->clear(1);                        
 
 3432       acl_update_user(combo->user.str, combo->host.str,
 
 3433                       combo->password.str, password_len,
 
 3443       acl_insert_user(combo->user.str, combo->host.str, password, password_len,
 
 3461 static int replace_db_table(
TABLE *table, 
const char *db,
 
 3463                             ulong rights, 
bool revoke_grant)
 
 3466   ulong priv,store_rights;
 
 3467   bool old_row_exists=0;
 
 3469   char what= (revoke_grant) ? 
'N' : 
'Y';
 
 3470   uchar user_key[MAX_KEY_LENGTH];
 
 3471   DBUG_ENTER(
"replace_db_table");
 
 3475     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--skip-grant-tables");
 
 3480   if (!find_acl_user(combo.host.str,combo.user.str, FALSE))
 
 3482     my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0));
 
 3486   table->use_all_columns();
 
 3487   table->field[0]->store(combo.host.str,combo.host.length,
 
 3488                          system_charset_info);
 
 3489   table->field[1]->store(db,(uint) strlen(db), system_charset_info);
 
 3490   table->field[2]->store(combo.user.str,combo.user.length,
 
 3491                          system_charset_info);
 
 3492   key_copy(user_key, table->record[0], table->key_info,
 
 3501       my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str);
 
 3505     restore_record(table, s->default_values);
 
 3506     table->field[0]->store(combo.host.str,combo.host.length,
 
 3507                            system_charset_info);
 
 3508     table->field[1]->store(db,(uint) strlen(db), system_charset_info);
 
 3509     table->field[2]->store(combo.user.str,combo.user.length,
 
 3510                            system_charset_info);
 
 3515     store_record(table,
record[1]);
 
 3518   store_rights=get_rights_for_db(rights);
 
 3519   for (i= 3, priv= 1; i < table->s->fields; i++, priv <<= 1)
 
 3521     if (priv & store_rights)                    
 
 3522       table->field [
i]->store(&what,1, &my_charset_latin1);
 
 3524   rights=get_access(table,3);
 
 3525   rights=fix_rights_for_db(rights);
 
 3532       if ((error= table->file->ha_update_row(table->record[1],
 
 3533                                              table->record[0])) &&
 
 3534           error != HA_ERR_RECORD_IS_THE_SAME)
 
 3539       if ((error= table->file->ha_delete_row(table->record[1])))
 
 3543   else if (rights && (error= table->file->ha_write_row(table->record[0])))
 
 3549   acl_cache->clear(1);                          
 
 3551     acl_update_db(combo.user.str,combo.host.str,db,rights);
 
 3554     acl_insert_db(combo.user.str,combo.host.str,db,rights);
 
 3571   DBUG_ENTER(
"acl_update_proxy_user");
 
 3572   for (uint i= 0; i < acl_proxy_users.elements; i++)
 
 3577     if (acl_user->pk_equals(new_value))
 
 3581         DBUG_PRINT(
"info", (
"delting ACL_PROXY_USER"));
 
 3582         delete_dynamic_element(&acl_proxy_users, i);
 
 3586         DBUG_PRINT(
"info", (
"updating ACL_PROXY_USER"));
 
 3587         acl_user->set_data(new_value);
 
 3599   DBUG_ENTER(
"acl_insert_proxy_user");
 
 3601   (void) push_dynamic(&acl_proxy_users, (uchar *) new_value);
 
 3602   my_qsort((uchar*) dynamic_element(&acl_proxy_users, 0, 
ACL_PROXY_USER *),
 
 3603            acl_proxy_users.elements,
 
 3610 replace_proxies_priv_table(THD *thd, 
TABLE *table, 
const LEX_USER *user,
 
 3611                          const LEX_USER *proxied_user, 
bool with_grant_arg, 
 
 3614   bool old_row_exists= 0;
 
 3616   uchar user_key[MAX_KEY_LENGTH];
 
 3618   char grantor[USER_HOST_BUFF_SIZE];
 
 3620   DBUG_ENTER(
"replace_proxies_priv_table");
 
 3624     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--skip-grant-tables");
 
 3629   if (!find_acl_user(user->host.str,user->user.str, FALSE))
 
 3631     my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0));
 
 3635   table->use_all_columns();
 
 3636   ACL_PROXY_USER::store_pk (table, &user->host, &user->user, 
 
 3637                             &proxied_user->host, &proxied_user->user);
 
 3639   key_copy(user_key, table->record[0], table->key_info,
 
 3642   get_grantor(thd, grantor);
 
 3647     DBUG_PRINT(
"info", (
"ha_index_init error"));
 
 3655     DBUG_PRINT (
"info", (
"Row not found"));
 
 3658       my_error(ER_NONEXISTING_GRANT, MYF(0), user->user.str, user->host.str);
 
 3662     restore_record(table, s->default_values);
 
 3663     ACL_PROXY_USER::store_data_record(table, &user->host, &user->user,
 
 3664                                       &proxied_user->host,
 
 3665                                       &proxied_user->user,
 
 3671     DBUG_PRINT(
"info", (
"Row found"));
 
 3673     store_record(table, 
record[1]);
 
 3681       if ((error= table->file->ha_update_row(table->record[1],
 
 3682                                              table->record[0])) &&
 
 3683           error != HA_ERR_RECORD_IS_THE_SAME)
 
 3688       if ((error= table->file->ha_delete_row(table->record[1])))
 
 3692   else if ((error= table->file->ha_write_row(table->record[0])))
 
 3694     DBUG_PRINT(
"info", (
"error inserting the row"));
 
 3699   acl_cache->clear(1);                          
 
 3702     new_grant.init(user->host.str, user->user.str,
 
 3703                    proxied_user->host.str, proxied_user->user.str,
 
 3705     acl_update_proxy_user(&new_grant, revoke_grant);
 
 3709     new_grant.init(&global_acl_memory, user->host.str, user->user.str,
 
 3710                    proxied_user->host.str, proxied_user->user.str,
 
 3712     acl_insert_proxy_user(&new_grant);
 
 3720   DBUG_PRINT(
"info", (
"table error"));
 
 3724   DBUG_PRINT(
"info", (
"aborting replace_proxies_priv_table"));
 
 3738     column= (
char*) memdup_root(&memex,c.ptr(), key_length=c.length());
 
 3743 static uchar* get_key_column(
GRANT_COLUMN *buff, 
size_t *length,
 
 3744                             my_bool not_used __attribute__((unused)))
 
 3746   *length=buff->key_length;
 
 3747   return (uchar*) buff->column;
 
 3755   char *db, *user, *tname, *hash_key;
 
 3759   GRANT_NAME(
const char *h, 
const char *d,
const char *u,
 
 3760              const char *t, ulong p, 
bool is_routine);
 
 3763   virtual bool ok() { 
return privs != 0; }
 
 3764   void set_user_details(
const char *h, 
const char *d,
 
 3765                         const char *u, 
const char *t,
 
 3776   GRANT_TABLE(
const char *h, 
const char *d,
const char *u,
 
 3777               const char *t, ulong p, ulong c);
 
 3780   bool ok() { 
return privs != 0 || cols != 0; }
 
 3784 void GRANT_NAME::set_user_details(
const char *h, 
const char *d,
 
 3785                                   const char *u, 
const char *t,
 
 3789   host.update_hostname(strdup_root(&memex, h));
 
 3792     db= strdup_root(&memex, d);
 
 3793     if (lower_case_table_names)
 
 3794       my_casedn_str(files_charset_info, db);
 
 3796   user = strdup_root(&memex,u);
 
 3797   sort=  get_sort(3,host.get_host(),db,user);
 
 3800     tname= strdup_root(&memex, t);
 
 3801     if (lower_case_table_names || is_routine)
 
 3802       my_casedn_str(files_charset_info, tname);
 
 3804   key_length= strlen(d) + strlen(u)+ strlen(t)+3;
 
 3805   hash_key=   (
char*) alloc_root(&memex,key_length);
 
 3806   strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
 
 3809 GRANT_NAME::GRANT_NAME(
const char *h, 
const char *d,
const char *u,
 
 3810                        const char *t, ulong p, 
bool is_routine)
 
 3811   :db(0), tname(0), privs(p)
 
 3813   set_user_details(h, d, u, t, is_routine);
 
 3816 GRANT_TABLE::GRANT_TABLE(
const char *h, 
const char *d,
const char *u,
 
 3817                          const char *t, ulong p, ulong c)
 
 3820   (void) my_hash_init2(&hash_columns,4,system_charset_info,
 
 3821                    0,0,0, (my_hash_get_key) get_key_column,0,0);
 
 3825 GRANT_NAME::GRANT_NAME(
TABLE *form, 
bool is_routine)
 
 3827   host.update_hostname(get_field(&memex, form->field[0]));
 
 3828   db=    get_field(&memex,form->field[1]);
 
 3829   user=  get_field(&memex,form->field[2]);
 
 3832   sort=  get_sort(3, host.get_host(), db, user);
 
 3833   tname= get_field(&memex,form->field[3]);
 
 3834   if (!db || !tname) {
 
 3839   if (lower_case_table_names)
 
 3841     my_casedn_str(files_charset_info, db);
 
 3843   if (lower_case_table_names || is_routine)
 
 3845     my_casedn_str(files_charset_info, tname);
 
 3847   key_length= (strlen(db) + strlen(user) + strlen(tname) + 3);
 
 3848   hash_key=   (
char*) alloc_root(&memex, key_length);
 
 3849   strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
 
 3850   privs = (ulong) form->field[6]->val_int();
 
 3851   privs = fix_rights_for_table(privs);
 
 3855 GRANT_TABLE::GRANT_TABLE(
TABLE *form, 
TABLE *col_privs)
 
 3858   uchar key[MAX_KEY_LENGTH];
 
 3863     my_hash_clear(&hash_columns);               
 
 3867   cols= (ulong) form->field[7]->val_int();
 
 3868   cols =  fix_rights_for_column(cols);
 
 3870   (void) my_hash_init2(&hash_columns,4,system_charset_info,
 
 3871                    0,0,0, (my_hash_get_key) get_key_column,0,0);
 
 3874     uint key_prefix_len;
 
 3876     col_privs->field[0]->store(host.get_host(),
 
 3877                                host.get_host() ? (uint) host.get_host_len() : 0,
 
 3878                                system_charset_info);
 
 3879     col_privs->field[1]->store(db,(uint) strlen(db), system_charset_info);
 
 3880     col_privs->field[2]->store(user,(uint) strlen(user), system_charset_info);
 
 3881     col_privs->field[3]->store(tname,(uint) strlen(tname), system_charset_info);
 
 3883     key_prefix_len= (key_part[0].store_length +
 
 3884                      key_part[1].store_length +
 
 3885                      key_part[2].store_length +
 
 3886                      key_part[3].store_length);
 
 3887     key_copy(key, col_privs->record[0], col_privs->key_info, key_prefix_len);
 
 3888     col_privs->field[4]->store(
"",0, &my_charset_latin1);
 
 3897                                            (key_part_map)15, HA_READ_KEY_EXACT))
 
 3908       res=col_privs->field[4]->val_str(&column_name);
 
 3909       ulong priv= (ulong) col_privs->field[6]->val_int();
 
 3911                                          fix_rights_for_column(priv))))
 
 3917       if (my_hash_insert(&hash_columns, (uchar *) mem_check))
 
 3923     } 
while (!col_privs->file->
ha_index_next(col_privs->record[0]) &&
 
 3924              !key_cmp_if_same(col_privs,key,0,key_prefix_len));
 
 3930 GRANT_TABLE::~GRANT_TABLE()
 
 3932   my_hash_free(&hash_columns);
 
 3936 static uchar* get_grant_table(
GRANT_NAME *buff, 
size_t *length,
 
 3937                              my_bool not_used __attribute__((unused)))
 
 3939   *length=buff->key_length;
 
 3940   return (uchar*) buff->hash_key;
 
 3946   my_hash_free(&grant_table->hash_columns);
 
 3953                                     const char *host,
const char* ip,
 
 3955                                     const char *user, 
const char *tname,
 
 3956                                     bool exact, 
bool name_tolower)
 
 3958   char helping [NAME_LEN*2+USERNAME_LENGTH+3], *name_ptr;
 
 3961   HASH_SEARCH_STATE state;
 
 3963   name_ptr= strmov(strmov(helping, user) + 1, db) + 1;
 
 3964   len  = (uint) (strmov(name_ptr, tname) - helping) + 1;
 
 3966     my_casedn_str(files_charset_info, name_ptr);
 
 3967   for (grant_name= (
GRANT_NAME*) my_hash_first(name_hash, (uchar*) helping,
 
 3970        grant_name= (
GRANT_NAME*) my_hash_next(name_hash,(uchar*) helping,
 
 3975       if (!grant_name->host.get_host() ||
 
 3977            !my_strcasecmp(system_charset_info, host,
 
 3978                           grant_name->host.get_host())) ||
 
 3979           (ip && !strcmp(ip, grant_name->host.get_host())))
 
 3984       if (grant_name->host.compare_hostname(host, ip) &&
 
 3985           (!found || found->sort < grant_name->sort))
 
 3994 routine_hash_search(
const char *host, 
const char *ip, 
const char *db,
 
 3995                  const char *user, 
const char *tname, 
bool proc, 
bool exact)
 
 3998     name_hash_search(proc ? &proc_priv_hash : &func_priv_hash,
 
 3999                      host, ip, db, user, tname, exact, TRUE);
 
 4004 table_hash_search(
const char *host, 
const char *ip, 
const char *db,
 
 4005                   const char *user, 
const char *tname, 
bool exact)
 
 4007   return (
GRANT_TABLE*) name_hash_search(&column_priv_hash, host, ip, db,
 
 4008                                          user, tname, exact, FALSE);
 
 4013 column_hash_search(
GRANT_TABLE *t, 
const char *cname, uint length)
 
 4015   return (
GRANT_COLUMN*) my_hash_search(&t->hash_columns,
 
 4016                                         (uchar*) cname, length);
 
 4024                                 ulong rights, 
bool revoke_grant)
 
 4027   uchar key[MAX_KEY_LENGTH];
 
 4028   uint key_prefix_length;
 
 4029   DBUG_ENTER(
"replace_column_table");
 
 4031   if (!table->key_info)
 
 4033     my_error(ER_TABLE_CORRUPT, MYF(0), table->s->db.str,
 
 4034              table->s->table_name.str);
 
 4040   table->use_all_columns();
 
 4041   table->field[0]->store(combo.host.str,combo.host.length,
 
 4042                          system_charset_info);
 
 4043   table->field[1]->store(db,(uint) strlen(db),
 
 4044                          system_charset_info);
 
 4045   table->field[2]->store(combo.user.str,combo.user.length,
 
 4046                          system_charset_info);
 
 4047   table->field[3]->store(table_name,(uint) strlen(table_name),
 
 4048                          system_charset_info);
 
 4051   key_prefix_length= (key_part[0].store_length + key_part[1].store_length +
 
 4052                       key_part[2].store_length + key_part[3].store_length);
 
 4053   key_copy(key, table->record[0], table->key_info, key_prefix_length);
 
 4068   while ((column= iter++))
 
 4070     ulong privileges= column->rights;
 
 4071     bool old_row_exists=0;
 
 4072     uchar user_key[MAX_KEY_LENGTH];
 
 4074     key_restore(table->record[0],key,table->key_info,
 
 4076     table->field[4]->store(column->column.ptr(), column->column.length(),
 
 4077                            system_charset_info);
 
 4079     key_copy(user_key, table->record[0], table->key_info,
 
 4087         my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
 
 4088                  combo.user.str, combo.host.str,
 
 4094       restore_record(table, s->default_values);         
 
 4095       key_restore(table->record[0],key,table->key_info,
 
 4097       table->field[4]->store(column->column.ptr(),column->column.length(),
 
 4098                              system_charset_info);
 
 4102       ulong tmp= (ulong) table->field[6]->val_int();
 
 4103       tmp=fix_rights_for_column(tmp);
 
 4106         privileges = tmp & ~(privileges | rights);
 
 4110       store_record(table,
record[1]);                    
 
 4113     table->field[6]->store((longlong) get_rights_for_column(privileges), TRUE);
 
 4119         error=table->file->ha_update_row(table->record[1],table->record[0]);
 
 4121         error=table->file->ha_delete_row(table->record[1]);
 
 4122       if (error && error != HA_ERR_RECORD_IS_THE_SAME)
 
 4130       grant_column= column_hash_search(g_t, column->column.ptr(),
 
 4131                                        column->column.length());
 
 4133         grant_column->rights= privileges;       
 
 4138       if ((error=table->file->ha_write_row(table->record[0])))
 
 4144       grant_column= 
new GRANT_COLUMN(column->column,privileges);
 
 4145       if (my_hash_insert(&g_t->hash_columns,(uchar*) grant_column))
 
 4160     uchar user_key[MAX_KEY_LENGTH];
 
 4161     key_copy(user_key, table->record[0], table->key_info,
 
 4172       ulong privileges = (ulong) table->field[6]->val_int();
 
 4173       privileges=fix_rights_for_column(privileges);
 
 4174       store_record(table,
record[1]);
 
 4176       if (privileges & rights)  
 
 4179         char  colum_name_buf[HOSTNAME_LENGTH+1];
 
 4180         String column_name(colum_name_buf,
sizeof(colum_name_buf),
 
 4181                            system_charset_info);
 
 4183         privileges&= ~rights;
 
 4184         table->field[6]->store((longlong)
 
 4185                                get_rights_for_column(privileges), TRUE);
 
 4186         table->field[4]->val_str(&column_name);
 
 4187         grant_column = column_hash_search(g_t,
 
 4189                                           column_name.length());
 
 4193           if ((tmp_error=table->file->ha_update_row(table->record[1],
 
 4194                                                     table->record[0])) &&
 
 4195               tmp_error != HA_ERR_RECORD_IS_THE_SAME)
 
 4202             grant_column->rights  = privileges; 
 
 4207           if ((tmp_error = table->file->ha_delete_row(table->record[1])))
 
 4214             my_hash_delete(&g_t->hash_columns,(uchar*) grant_column);
 
 4218              !key_cmp_if_same(table, key, 0, key_prefix_length));
 
 4223   DBUG_RETURN(result);
 
 4226 static inline void get_grantor(THD *thd, 
char *grantor)
 
 4228   const char *user= thd->security_ctx->user;
 
 4229   const char *host= thd->security_ctx->host_or_ip;
 
 4231 #if defined(HAVE_REPLICATION) 
 4232   if (thd->slave_thread && thd->has_invoker())
 
 4234     user= thd->get_invoker_user().str;
 
 4235     host= thd->get_invoker_host().str;
 
 4238   strxmov(grantor, user, 
"@", host, NullS);
 
 4241 static int replace_table_table(THD *thd, 
GRANT_TABLE *grant_table,
 
 4243                                const char *db, 
const char *table_name,
 
 4244                                ulong rights, ulong col_rights,
 
 4247   char grantor[USER_HOST_BUFF_SIZE];
 
 4248   int old_row_exists = 1;
 
 4250   ulong store_table_rights, store_col_rights;
 
 4251   uchar user_key[MAX_KEY_LENGTH];
 
 4252   DBUG_ENTER(
"replace_table_table");
 
 4254   get_grantor(thd, grantor);
 
 4259   if (!find_acl_user(combo.host.str,combo.user.str, FALSE))
 
 4261     my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH),
 
 4266   table->use_all_columns();
 
 4267   restore_record(table, s->default_values);     
 
 4268   table->field[0]->store(combo.host.str,combo.host.length,
 
 4269                          system_charset_info);
 
 4270   table->field[1]->store(db,(uint) strlen(db), system_charset_info);
 
 4271   table->field[2]->store(combo.user.str,combo.user.length,
 
 4272                          system_charset_info);
 
 4273   table->field[3]->store(table_name,(uint) strlen(table_name),
 
 4274                          system_charset_info);
 
 4275   store_record(table,
record[1]);                        
 
 4276   key_copy(user_key, table->record[0], table->key_info,
 
 4290       my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
 
 4291                combo.user.str, combo.host.str,
 
 4296     restore_record(table,
record[1]);                    
 
 4299   store_table_rights= get_rights_for_table(rights);
 
 4300   store_col_rights=   get_rights_for_column(col_rights);
 
 4304     store_record(table,
record[1]);
 
 4305     j = (ulong) table->field[6]->val_int();
 
 4306     k = (ulong) table->field[7]->val_int();
 
 4311       store_table_rights=j & ~store_table_rights;
 
 4315       store_table_rights|= j;
 
 4316       store_col_rights|=   k;
 
 4320   table->field[4]->store(grantor,(uint) strlen(grantor), system_charset_info);
 
 4321   table->field[6]->store((longlong) store_table_rights, TRUE);
 
 4322   table->field[7]->store((longlong) store_col_rights, TRUE);
 
 4323   rights=fix_rights_for_table(store_table_rights);
 
 4324   col_rights=fix_rights_for_column(store_col_rights);
 
 4328     if (store_table_rights || store_col_rights)
 
 4330       if ((error=table->file->ha_update_row(table->record[1],
 
 4331                                             table->record[0])) &&
 
 4332           error != HA_ERR_RECORD_IS_THE_SAME)
 
 4335     else if ((error = table->file->ha_delete_row(table->record[1])))
 
 4340     error=table->file->ha_write_row(table->record[0]);
 
 4345   if (rights | col_rights)
 
 4347     grant_table->privs= rights;
 
 4348     grant_table->cols=  col_rights;
 
 4352     my_hash_delete(&column_priv_hash,(uchar*) grant_table);
 
 4367 static int replace_routine_table(THD *thd, 
GRANT_NAME *grant_name,
 
 4369                               const char *db, 
const char *routine_name,
 
 4370                               bool is_proc, ulong rights, 
bool revoke_grant)
 
 4372   char grantor[USER_HOST_BUFF_SIZE];
 
 4373   int old_row_exists= 1;
 
 4375   ulong store_proc_rights;
 
 4376   DBUG_ENTER(
"replace_routine_table");
 
 4380     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--skip-grant-tables");
 
 4384   get_grantor(thd, grantor);
 
 4392   table->use_all_columns();
 
 4393   restore_record(table, s->default_values);             
 
 4394   table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1);
 
 4395   table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1);
 
 4396   table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1);
 
 4397   table->field[3]->store(routine_name,(uint) strlen(routine_name),
 
 4398                          &my_charset_latin1);
 
 4399   table->field[4]->store((longlong)(is_proc ?
 
 4400                                     SP_TYPE_PROCEDURE : SP_TYPE_FUNCTION),
 
 4402   store_record(table,
record[1]);                        
 
 4405                                          (uchar*) table->field[0]->ptr,
 
 4416       my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
 
 4417                combo.user.str, combo.host.str, routine_name);
 
 4421     restore_record(table,
record[1]);                    
 
 4424   store_proc_rights= get_rights_for_procedure(rights);
 
 4428     store_record(table,
record[1]);
 
 4429     j= (ulong) table->field[6]->val_int();
 
 4434       store_proc_rights=j & ~store_proc_rights;
 
 4438       store_proc_rights|= j;
 
 4442   table->field[5]->store(grantor,(uint) strlen(grantor), &my_charset_latin1);
 
 4443   table->field[6]->store((longlong) store_proc_rights, TRUE);
 
 4444   rights=fix_rights_for_procedure(store_proc_rights);
 
 4448     if (store_proc_rights)
 
 4450       if ((error=table->file->ha_update_row(table->record[1],
 
 4451                                             table->record[0])) &&
 
 4452           error != HA_ERR_RECORD_IS_THE_SAME)
 
 4455     else if ((error= table->file->ha_delete_row(table->record[1])))
 
 4460     error=table->file->ha_write_row(table->record[0]);
 
 4467     grant_name->privs= rights;
 
 4471     my_hash_delete(is_proc ? &proc_priv_hash : &func_priv_hash,(uchar*)
 
 4500 int mysql_table_grant(THD *thd, 
TABLE_LIST *table_list,
 
 4505   ulong column_priv= 0;
 
 4509   bool create_new_users=0;
 
 4511   bool save_binlog_row_based;
 
 4512   bool transactional_tables;
 
 4513   DBUG_ENTER(
"mysql_table_grant");
 
 4517     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
 
 4518              "--skip-grant-tables");    
 
 4521   if (rights & ~TABLE_ACLS)
 
 4523     my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
 
 4530     if (columns.elements)
 
 4538       while ((column = column_iter++))
 
 4540         uint unused_field_idx= NO_CACHED_FIELD_INDEX;
 
 4542         Field *f=find_field_in_table_ref(thd, table_list, column->column.ptr(),
 
 4543                                          column->column.length(),
 
 4544                                          column->column.ptr(), NULL, NULL,
 
 4546                                          &unused_field_idx, FALSE, &dummy);
 
 4549           my_error(ER_BAD_FIELD_ERROR, MYF(0),
 
 4550                    column->column.c_ptr(), table_list->alias);
 
 4553         if (f == (
Field *)-1)
 
 4555         column_priv|= column->rights;
 
 4561       if (!(rights & CREATE_ACL))
 
 4563         char buf[FN_REFLEN + 1];
 
 4564         build_table_filename(buf, 
sizeof(buf) - 1, table_list->db,
 
 4565                              table_list->table_name, reg_ext, 0);
 
 4566         fn_format(buf, buf, 
"", 
"", MY_UNPACK_FILENAME  | MY_RESOLVE_SYMLINKS |
 
 4567                                     MY_RETURN_REAL_PATH | MY_APPEND_EXT);
 
 4568         if (access(buf,F_OK))
 
 4570           my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
 
 4577         get_privilege_desc(command, 
sizeof(command),
 
 4579         my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
 
 4580                  command, thd->security_ctx->priv_user,
 
 4581                  thd->security_ctx->host_or_ip, table_list->alias);
 
 4590                            C_STRING_WITH_LEN(
"user"), 
"user", TL_WRITE);
 
 4592                            C_STRING_WITH_LEN(
"tables_priv"),
 
 4593                            "tables_priv", TL_WRITE);
 
 4595                            C_STRING_WITH_LEN(
"columns_priv"),
 
 4596                            "columns_priv", TL_WRITE);
 
 4597   tables[0].next_local= tables[0].next_global= tables+1;
 
 4599   if (column_priv || (revoke_grant && ((rights & COL_ACLS) || columns.elements)))
 
 4600     tables[1].next_local= tables[1].next_global= tables+2;
 
 4607   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 4608     thd->clear_current_stmt_binlog_format_row();
 
 4610 #ifdef HAVE_REPLICATION 
 4615   if (thd->slave_thread && rpl_filter->is_on())
 
 4621     tables[0].updating= tables[1].updating= tables[2].updating= 1;
 
 4622     if (!(thd->sp_runtime_ctx || rpl_filter->tables_ok(0, tables)))
 
 4625       DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 4626       if (save_binlog_row_based)
 
 4627         thd->set_current_stmt_binlog_format_row();
 
 4637   Query_tables_list backup;
 
 4638   thd->lex->reset_n_backup_query_tables_list(&backup);
 
 4644   thd->lex->sql_command= backup.sql_command;
 
 4648     DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 4649     thd->lex->restore_backup_query_tables_list(&backup);
 
 4650     if (save_binlog_row_based)
 
 4651       thd->set_current_stmt_binlog_format_row();
 
 4655   transactional_tables= (tables[0].table->file->has_transactions() ||
 
 4656                          tables[1].table->file->has_transactions() ||
 
 4658                           tables[2].table->file->has_transactions()));
 
 4661     create_new_users= test_if_create_new_users(thd);
 
 4666   thd->mem_root= &memex;
 
 4669   while ((tmp_Str = str_list++))
 
 4684     if (!tmp_Str->user.str && tmp_Str->password.str)
 
 4685       Str->password= tmp_Str->password;
 
 4688     error=replace_user_table(thd, tables[0].table, Str,
 
 4689                              0, revoke_grant, create_new_users,
 
 4690                              test(thd->variables.sql_mode &
 
 4691                                   MODE_NO_AUTO_CREATE_USER));
 
 4699     thd->add_to_binlog_accessed_dbs(db_name); 
 
 4703     grant_table= table_hash_search(Str->host.str, NullS, db_name,
 
 4704                                    Str->user.str, table_name, 1);
 
 4709         my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0),
 
 4710                  Str->user.str, Str->host.str, table_list->table_name);
 
 4714       grant_table = 
new GRANT_TABLE (Str->host.str, db_name,
 
 4715                                      Str->user.str, table_name,
 
 4719         my_hash_insert(&column_priv_hash,(uchar*) grant_table))
 
 4734       while ((column = column_iter++))
 
 4736         grant_column = column_hash_search(grant_table,
 
 4737                                           column->column.ptr(),
 
 4738                                           column->column.length());
 
 4740           grant_column->rights&= ~(column->rights | rights);
 
 4744       for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++)
 
 4747           my_hash_element(&grant_table->hash_columns, idx);
 
 4748         grant_column->rights&= ~rights;         
 
 4749         column_priv|= grant_column->rights;
 
 4754       column_priv|= grant_table->cols;
 
 4760     if (replace_table_table(thd, grant_table, tables[1].table, *Str,
 
 4761                             db_name, table_name,
 
 4762                             rights, column_priv, revoke_grant))
 
 4767     else if (tables[2].table)
 
 4769       if ((replace_column_table(grant_table, tables[2].table, *Str,
 
 4771                                 db_name, table_name,
 
 4772                                 rights, revoke_grant)))
 
 4778   thd->mem_root= old_root;
 
 4796             write_bin_log(thd, FALSE, thd->query(), thd->query_length(),
 
 4797                           transactional_tables);
 
 4801   result|= acl_trans_commit_and_close_tables(thd);
 
 4806   thd->lex->restore_backup_query_tables_list(&backup);
 
 4808   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 4809   if (save_binlog_row_based)
 
 4810     thd->set_current_stmt_binlog_format_row();
 
 4811   DBUG_RETURN(result);
 
 4830 bool mysql_routine_grant(THD *thd, 
TABLE_LIST *table_list, 
bool is_proc,
 
 4832                          bool revoke_grant, 
bool write_to_binlog)
 
 4837   bool create_new_users=0, result=0;
 
 4839   bool save_binlog_row_based;
 
 4840   bool transactional_tables;
 
 4841   DBUG_ENTER(
"mysql_routine_grant");
 
 4845     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
 
 4846              "--skip-grant-tables");
 
 4849   if (rights & ~PROC_ACLS)
 
 4851     my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
 
 4858     if (sp_exist_routines(thd, table_list, is_proc))
 
 4865                            C_STRING_WITH_LEN(
"user"), 
"user", TL_WRITE);
 
 4867                            C_STRING_WITH_LEN(
"procs_priv"), 
"procs_priv", TL_WRITE);
 
 4868   tables[0].next_local= tables[0].next_global= tables+1;
 
 4875   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 4876     thd->clear_current_stmt_binlog_format_row();
 
 4878 #ifdef HAVE_REPLICATION 
 4883   if (thd->slave_thread && rpl_filter->is_on())
 
 4889     tables[0].updating= tables[1].updating= 1;
 
 4890     if (!(thd->sp_runtime_ctx || rpl_filter->tables_ok(0, tables)))
 
 4893       DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 4894       if (save_binlog_row_based)
 
 4895         thd->set_current_stmt_binlog_format_row();
 
 4904     DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 4905     if (save_binlog_row_based)
 
 4906       thd->set_current_stmt_binlog_format_row();
 
 4910   transactional_tables= (tables[0].table->file->has_transactions() ||
 
 4911                          tables[1].table->file->has_transactions());
 
 4914     create_new_users= test_if_create_new_users(thd);
 
 4918   thd->mem_root= &memex;
 
 4920   DBUG_PRINT(
"info",(
"now time to iterate and add users"));
 
 4922   while ((tmp_Str= str_list++))
 
 4933     error=replace_user_table(thd, tables[0].table, Str,
 
 4934                              0, revoke_grant, create_new_users,
 
 4935                              test(thd->variables.sql_mode &
 
 4936                                   MODE_NO_AUTO_CREATE_USER));
 
 4943     db_name= table_list->db;
 
 4944     if (write_to_binlog)
 
 4945       thd->add_to_binlog_accessed_dbs(db_name);
 
 4946     table_name= table_list->table_name;
 
 4947     grant_name= routine_hash_search(Str->host.str, NullS, db_name,
 
 4948                                     Str->user.str, table_name, is_proc, 1);
 
 4953         my_error(ER_NONEXISTING_PROC_GRANT, MYF(0),
 
 4954                  Str->user.str, Str->host.str, table_name);
 
 4958       grant_name= 
new GRANT_NAME(Str->host.str, db_name,
 
 4959                                  Str->user.str, table_name,
 
 4962         my_hash_insert(is_proc ?
 
 4963                        &proc_priv_hash : &func_priv_hash,(uchar*) grant_name))
 
 4970     if (replace_routine_table(thd, grant_name, tables[1].table, *Str,
 
 4971                               db_name, table_name, is_proc, rights, 
 
 4978   thd->mem_root= old_root;
 
 4981   if (write_to_binlog)
 
 4991       if (!thd->rewritten_query.length())
 
 4993         if (write_bin_log(thd, 
false, thd->query(), thd->query_length(),
 
 4994                           transactional_tables))
 
 4999         if (write_bin_log(thd, 
false,
 
 5000                           thd->rewritten_query.c_ptr_safe(),
 
 5001                           thd->rewritten_query.length(),
 
 5002                           transactional_tables))
 
 5010   result|= acl_trans_commit_and_close_tables(thd);
 
 5013   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 5014   if (save_binlog_row_based)
 
 5015     thd->set_current_stmt_binlog_format_row();
 
 5017   DBUG_RETURN(result);
 
 5035 int digest_password(THD *thd, 
LEX_USER *user_record)
 
 5038   if (user_record->password.length == 0)
 
 5041 #if defined(HAVE_OPENSSL) 
 5045   if (user_record->plugin.str == sha256_password_plugin_name.str)
 
 5047     char *buff=  (
char *) thd->alloc(CRYPT_MAX_PASSWORD_SIZE+1);
 
 5051     my_make_scrambled_password(buff, user_record->password.str,
 
 5052                                user_record->password.length);
 
 5053     user_record->password.str= buff;
 
 5054     user_record->password.length= strlen(buff)+1;
 
 5058   if (user_record->plugin.str == native_password_plugin_name.str ||
 
 5059       user_record->plugin.str == old_password_plugin_name.str)
 
 5061     if (thd->variables.old_passwords == 1)
 
 5064         (
char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
 
 5068       my_make_scrambled_password_323(buff, user_record->password.str,
 
 5069                                      user_record->password.length);
 
 5070       user_record->password.str= buff;
 
 5071       user_record->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
 
 5076         (
char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
 
 5080       my_make_scrambled_password_sha1(buff, user_record->password.str,
 
 5081                                       user_record->password.length);
 
 5082       user_record->password.str= buff;
 
 5083       user_record->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
 
 5088     user_record->password.str= 0;
 
 5089     user_record->password.length= 0;
 
 5095                  ulong rights, 
bool revoke_grant, 
bool is_proxy)
 
 5098   LEX_USER *Str, *tmp_Str, *proxied_user= NULL;
 
 5099   char tmp_db[NAME_LEN+1];
 
 5100   bool create_new_users=0;
 
 5102   bool save_binlog_row_based;
 
 5103   bool transactional_tables;
 
 5104   DBUG_ENTER(
"mysql_grant");
 
 5107     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
 
 5108              "--skip-grant-tables");    
 
 5112   if (lower_case_table_names && db)
 
 5114     strnmov(tmp_db,db,NAME_LEN);
 
 5115     tmp_db[NAME_LEN]= 
'\0';
 
 5116     my_casedn_str(files_charset_info, tmp_db);
 
 5123     proxied_user= str_list++;
 
 5128                            C_STRING_WITH_LEN(
"user"), 
"user", TL_WRITE);
 
 5132                              C_STRING_WITH_LEN(
"proxies_priv"),
 
 5137                              C_STRING_WITH_LEN(
"db"), 
 
 5140   tables[0].next_local= tables[0].next_global= tables+1;
 
 5147   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 5148     thd->clear_current_stmt_binlog_format_row();
 
 5150 #ifdef HAVE_REPLICATION 
 5155   if (thd->slave_thread && rpl_filter->is_on())
 
 5161     tables[0].updating= tables[1].updating= 1;
 
 5162     if (!(thd->sp_runtime_ctx || rpl_filter->tables_ok(0, tables)))
 
 5165       DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 5166       if (save_binlog_row_based)
 
 5167         thd->set_current_stmt_binlog_format_row();
 
 5176     DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 5177     if (save_binlog_row_based)
 
 5178       thd->set_current_stmt_binlog_format_row();
 
 5182   transactional_tables= (tables[0].table->file->has_transactions() ||
 
 5183                          tables[1].table->file->has_transactions());
 
 5186     create_new_users= test_if_create_new_users(thd);
 
 5194   while ((tmp_Str = str_list++))
 
 5207     if (!tmp_Str->user.str && tmp_Str->password.str)
 
 5208       Str->password= tmp_Str->password;
 
 5210     if (replace_user_table(thd, tables[0].table, Str,
 
 5211                            (!db ? rights : 0), revoke_grant, create_new_users,
 
 5212                            test(thd->variables.sql_mode &
 
 5213                                 MODE_NO_AUTO_CREATE_USER)))
 
 5217       ulong db_rights= rights & DB_ACLS;
 
 5218       if (db_rights  == rights)
 
 5220         if (replace_db_table(tables[1].table, db, *Str, db_rights,
 
 5226         my_error(ER_WRONG_USAGE, MYF(0), 
"DB GRANT", 
"GLOBAL PRIVILEGES");
 
 5229       thd->add_to_binlog_accessed_dbs(db);
 
 5233       if (replace_proxies_priv_table (thd, tables[1].table, Str, proxied_user,
 
 5234                                     rights & GRANT_ACL ? TRUE : FALSE, 
 
 5245     if (thd->rewritten_query.length())
 
 5247           write_bin_log(thd, FALSE,
 
 5248                         thd->rewritten_query.c_ptr_safe(),
 
 5249                         thd->rewritten_query.length(),
 
 5250                         transactional_tables);
 
 5253               write_bin_log(thd, FALSE, thd->query(), thd->query_length(),
 
 5254                             transactional_tables);
 
 5259   result|= acl_trans_commit_and_close_tables(thd);
 
 5265   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 5266   if (save_binlog_row_based)
 
 5267     thd->set_current_stmt_binlog_format_row();
 
 5269   DBUG_RETURN(result);
 
 5275 void  grant_free(
void)
 
 5277   DBUG_ENTER(
"grant_free");
 
 5278   my_hash_free(&column_priv_hash);
 
 5279   my_hash_free(&proc_priv_hash);
 
 5280   my_hash_free(&func_priv_hash);
 
 5281   free_root(&memex,MYF(0));
 
 5295 my_bool grant_init()
 
 5299   DBUG_ENTER(
"grant_init");
 
 5301   if (!(thd= 
new THD))
 
 5303   thd->thread_stack= (
char*) &thd;
 
 5304   thd->store_globals();
 
 5305   return_val=  grant_reload(thd);
 
 5308   my_pthread_setspecific_ptr(THR_THD,  0);
 
 5309   DBUG_RETURN(return_val);
 
 5328 static my_bool grant_load_procs_priv(
TABLE *p_table)
 
 5331   my_bool return_val= 1;
 
 5332   bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
 
 5335   DBUG_ENTER(
"grant_load_procs_priv");
 
 5336   (void) my_hash_init(&proc_priv_hash, &my_charset_utf8_bin,
 
 5337                       0,0,0, (my_hash_get_key) get_grant_table,
 
 5339   (void) my_hash_init(&func_priv_hash, &my_charset_utf8_bin,
 
 5340                       0,0,0, (my_hash_get_key) get_grant_table,
 
 5344   p_table->use_all_columns();
 
 5349     my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr);
 
 5354       if (!(mem_check=
new (memex_ptr) 
GRANT_NAME(p_table, TRUE)))
 
 5360       if (check_no_resolve)
 
 5362         if (hostname_requires_resolving(mem_check->host.get_host()))
 
 5364           sql_print_warning(
"'procs_priv' entry '%s %s@%s' " 
 5365                             "ignored in --skip-name-resolve mode.",
 
 5366                             mem_check->tname, mem_check->user,
 
 5367                             mem_check->host.get_host() ?
 
 5368                             mem_check->host.get_host() : 
"");
 
 5372       if (p_table->field[4]->val_int() == SP_TYPE_PROCEDURE)
 
 5374         hash= &proc_priv_hash;
 
 5377       if (p_table->field[4]->val_int() == SP_TYPE_FUNCTION)
 
 5379         hash= &func_priv_hash;
 
 5383         sql_print_warning(
"'procs_priv' entry '%s' " 
 5384                           "ignored, bad routine type",
 
 5389       mem_check->privs= fix_rights_for_procedure(mem_check->privs);
 
 5390       if (! mem_check->ok())
 
 5392       else if (my_hash_insert(hash, (uchar*) mem_check))
 
 5405   my_pthread_setspecific_ptr(THR_MALLOC, save_mem_root_ptr);
 
 5406   DBUG_RETURN(return_val);
 
 5425 static my_bool grant_load(THD *thd, 
TABLE_LIST *tables)
 
 5428   my_bool return_val= 1;
 
 5429   TABLE *t_table= 0, *c_table= 0;
 
 5430   bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
 
 5433   sql_mode_t old_sql_mode= thd->variables.sql_mode;
 
 5434   DBUG_ENTER(
"grant_load");
 
 5436   thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
 
 5438   (void) my_hash_init(&column_priv_hash, &my_charset_utf8_bin,
 
 5439                       0,0,0, (my_hash_get_key) get_grant_table,
 
 5440                       (my_hash_free_key) free_grant_table,0);
 
 5442   t_table = tables[0].table;
 
 5443   c_table = tables[1].table;
 
 5445     goto end_index_init;
 
 5446   t_table->use_all_columns();
 
 5447   c_table->use_all_columns();
 
 5452     my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr);
 
 5456       if (!(mem_check=
new (memex_ptr) 
GRANT_TABLE(t_table,c_table)))
 
 5462       if (check_no_resolve)
 
 5464         if (hostname_requires_resolving(mem_check->host.get_host()))
 
 5466           sql_print_warning(
"'tables_priv' entry '%s %s@%s' " 
 5467                             "ignored in --skip-name-resolve mode.",
 
 5469                             mem_check->user ? mem_check->user : 
"",
 
 5470                             mem_check->host.get_host() ?
 
 5471                             mem_check->host.get_host() : 
"");
 
 5476       if (! mem_check->ok())
 
 5478       else if (my_hash_insert(&column_priv_hash,(uchar*) mem_check))
 
 5491   my_pthread_setspecific_ptr(THR_MALLOC, save_mem_root_ptr);
 
 5493   thd->variables.sql_mode= old_sql_mode;
 
 5494   DBUG_RETURN(return_val);
 
 5511 static my_bool grant_reload_procs_priv(THD *thd)
 
 5513   HASH old_proc_priv_hash, old_func_priv_hash;
 
 5515   my_bool return_val= FALSE;
 
 5516   DBUG_ENTER(
"grant_reload_procs_priv");
 
 5519                        strlen(
"procs_priv"), 
"procs_priv",
 
 5528   old_proc_priv_hash= proc_priv_hash;
 
 5529   old_func_priv_hash= func_priv_hash;
 
 5531   if ((return_val= grant_load_procs_priv(table.table)))
 
 5534     DBUG_PRINT(
"error",(
"Reverting to old privileges"));
 
 5536     proc_priv_hash= old_proc_priv_hash;
 
 5537     func_priv_hash= old_func_priv_hash;
 
 5541     my_hash_free(&old_proc_priv_hash);
 
 5542     my_hash_free(&old_func_priv_hash);
 
 5546   DBUG_RETURN(return_val);
 
 5565 my_bool grant_reload(THD *thd)
 
 5568   HASH old_column_priv_hash;
 
 5570   my_bool return_val= 1;
 
 5571   DBUG_ENTER(
"grant_reload");
 
 5578                            C_STRING_WITH_LEN(
"tables_priv"),
 
 5579                            "tables_priv", TL_READ);
 
 5581                            C_STRING_WITH_LEN(
"columns_priv"),
 
 5582                            "columns_priv", TL_READ);
 
 5583   tables[0].next_local= tables[0].next_global= tables+1;
 
 5594   old_column_priv_hash= column_priv_hash;
 
 5601   init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0);
 
 5603   if ((return_val= grant_load(thd, tables)))
 
 5605     DBUG_PRINT(
"error",(
"Reverting to old privileges"));
 
 5607     column_priv_hash= old_column_priv_hash;     
 
 5612     my_hash_free(&old_column_priv_hash);
 
 5613     free_root(&old_mem,MYF(0));
 
 5616   close_acl_tables(thd);
 
 5622   if (grant_reload_procs_priv(thd))
 
 5630   close_acl_tables(thd);
 
 5631   DBUG_RETURN(return_val);
 
 5674 bool check_grant(THD *thd, ulong want_access, 
TABLE_LIST *tables,
 
 5675                  bool any_combination_will_do, uint number, 
bool no_errors)
 
 5678   TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
 
 5679   Security_context *sctx= thd->security_ctx;
 
 5681   ulong orig_want_access= want_access;
 
 5682   DBUG_ENTER(
"check_grant");
 
 5683   DBUG_ASSERT(number > 0);
 
 5695   for (i= 0, tl= tables;
 
 5696        i < number  && tl != first_not_own_table;
 
 5697        tl= tl->next_global, i++)
 
 5708        tl && number-- && tl != first_not_own_table;
 
 5709        tl= tl->next_global)
 
 5711     sctx = 
test(tl->security_ctx) ? tl->security_ctx : thd->security_ctx;
 
 5714       get_cached_table_access(&tl->grant.
m_internal,
 
 5722       case ACL_INTERNAL_ACCESS_GRANTED:
 
 5730       case ACL_INTERNAL_ACCESS_DENIED:
 
 5732       case ACL_INTERNAL_ACCESS_CHECK_GRANT:
 
 5737     want_access= orig_want_access;
 
 5738     want_access&= ~sctx->master_access;
 
 5742     if (!(~tl->grant.
privilege & want_access) ||
 
 5749       if (!tl->referencing_view)
 
 5761     if (is_temporary_table(tl))
 
 5774     GRANT_TABLE *grant_table= table_hash_search(sctx->get_host()->ptr(),
 
 5775                                                 sctx->get_ip()->ptr(),
 
 5791     if (any_combination_will_do)
 
 5795     tl->grant.
version= grant_version;
 
 5796     tl->grant.
privilege|= grant_table->privs;
 
 5799     if (!(~tl->grant.
privilege & want_access))
 
 5802     if (want_access & ~(grant_table->cols | tl->grant.
privilege))
 
 5804       want_access &= ~(grant_table->cols | tl->grant.
privilege);
 
 5816     get_privilege_desc(command, 
sizeof(command), want_access);
 
 5817     my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
 
 5845 bool check_grant_column(THD *thd, 
GRANT_INFO *grant,
 
 5846                         const char *db_name, 
const char *table_name,
 
 5847                         const char *
name, uint length,  Security_context *sctx)
 
 5852   DBUG_ENTER(
"check_grant_column");
 
 5853   DBUG_PRINT(
"enter", (
"table: %s  want_access: %lu", table_name, want_access));
 
 5862   if (grant->
version != grant_version)
 
 5865       table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
 
 5866                         db_name, sctx->priv_user,
 
 5868     grant->
version= grant_version;              
 
 5873   grant_column=column_hash_search(grant_table, name, length);
 
 5874   if (grant_column && !(~grant_column->rights & want_access))
 
 5883   get_privilege_desc(command, 
sizeof(command), want_access);
 
 5884   my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
 
 5916 bool check_column_grant_in_table_ref(THD *thd, 
TABLE_LIST * table_ref,
 
 5917                                      const char *name, uint length)
 
 5920   const char *db_name;
 
 5922   Security_context *sctx= 
test(table_ref->security_ctx) ?
 
 5923                           table_ref->security_ctx : thd->security_ctx;
 
 5925   if (table_ref->view || table_ref->field_translation)
 
 5929     grant= &(table_ref->grant);
 
 5930     db_name= table_ref->view_db.str;
 
 5931     table_name= table_ref->view_name.str;
 
 5932     if (table_ref->belong_to_view && 
 
 5933         thd->lex->sql_command == SQLCOM_SHOW_FIELDS)
 
 5935       view_privs= get_column_grant(thd, grant, db_name, table_name, name);
 
 5936       if (view_privs & VIEW_ANY_ACL)
 
 5938         table_ref->belong_to_view->allowed_show= TRUE;
 
 5941       table_ref->belong_to_view->allowed_show= FALSE;
 
 5942       my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0));
 
 5949     TABLE *table= table_ref->table;
 
 5950     grant= &(table->grant);
 
 5951     db_name= table->s->db.str;
 
 5952     table_name= table->s->table_name.str;
 
 5956     return check_grant_column(thd, grant, db_name, table_name, name,
 
 5979 bool check_grant_all_columns(THD *thd, ulong want_access_arg, 
 
 5982   Security_context *sctx= thd->security_ctx;
 
 5983   ulong want_access= want_access_arg;
 
 5984   const char *table_name= NULL;
 
 5986   const char* db_name; 
 
 5994   bool using_column_privileges= FALSE;
 
 5998   for (; !fields->end_of_fields(); fields->next())
 
 6000     const char *field_name= fields->name();
 
 6002     if (table_name != fields->get_table_name())
 
 6004       table_name= fields->get_table_name();
 
 6005       db_name= fields->get_db_name();
 
 6006       grant= fields->grant();
 
 6008       want_access= want_access_arg & ~grant->
privilege;
 
 6012         if (grant->
version != grant_version)
 
 6015             table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
 
 6016                               db_name, sctx->priv_user,
 
 6018           grant->
version= grant_version;        
 
 6022         DBUG_ASSERT (grant_table);
 
 6029         column_hash_search(grant_table, field_name,
 
 6030                            (uint) strlen(field_name));
 
 6032         using_column_privileges= TRUE;
 
 6033       if (!grant_column || (~grant_column->rights & want_access))
 
 6044   get_privilege_desc(command, 
sizeof(command), want_access);
 
 6049   if (using_column_privileges)
 
 6050     my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
 
 6051              command, sctx->priv_user,
 
 6052              sctx->host_or_ip, table_name); 
 
 6054     my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
 
 6064 static bool check_grant_db_routine(THD *thd, 
const char *db, 
HASH *hash)
 
 6066   Security_context *sctx= thd->security_ctx;
 
 6068   for (uint idx= 0; idx < hash->records; ++idx)
 
 6072     if (strcmp(item->user, sctx->priv_user) == 0 &&
 
 6073         strcmp(item->db, db) == 0 &&
 
 6074         item->host.compare_hostname(sctx->get_host()->ptr(),
 
 6075                                     sctx->get_ip()->ptr()))
 
 6091 bool check_grant_db(THD *thd,
const char *db)
 
 6093   Security_context *sctx= thd->security_ctx;
 
 6094   char helping [NAME_LEN+USERNAME_LENGTH+2];
 
 6099   copy_length= (size_t) (strlen(sctx->priv_user ? sctx->priv_user : 
"") +
 
 6100                  strlen(db ? db : 
""));
 
 6105   if (copy_length >= (NAME_LEN+USERNAME_LENGTH+2))
 
 6108   len= (uint) (strmov(strmov(helping, sctx->priv_user) + 1, db) - helping) + 1;
 
 6112   for (uint idx=0 ; idx < column_priv_hash.records ; idx++)
 
 6115       my_hash_element(&column_priv_hash,
 
 6117     if (len < grant_table->key_length &&
 
 6118         !memcmp(grant_table->hash_key,helping,len) &&
 
 6119         grant_table->host.compare_hostname(sctx->get_host()->ptr(),
 
 6120                                            sctx->get_ip()->ptr()))
 
 6128     error= check_grant_db_routine(thd, db, &proc_priv_hash) &&
 
 6129            check_grant_db_routine(thd, db, &func_priv_hash);
 
 6154 bool check_grant_routine(THD *thd, ulong want_access,
 
 6155                          TABLE_LIST *procs, 
bool is_proc, 
bool no_errors)
 
 6158   Security_context *sctx= thd->security_ctx;
 
 6159   char *user= sctx->priv_user;
 
 6160   char *host= sctx->priv_host;
 
 6161   DBUG_ENTER(
"check_grant_routine");
 
 6163   want_access&= ~sctx->master_access;
 
 6168   for (table= procs; 
table; table= table->next_global)
 
 6171     if ((grant_proc= routine_hash_search(host, sctx->get_ip()->ptr(), table->db,
 
 6172                                          user, table->table_name, is_proc, 0)))
 
 6173       table->grant.
privilege|= grant_proc->privs;
 
 6175     if (want_access & ~table->grant.
privilege)
 
 6188     const char *command=
"";
 
 6190       strxmov(buff, table->db, 
".", table->table_name, NullS);
 
 6191     if (want_access & EXECUTE_ACL)
 
 6193     else if (want_access & ALTER_PROC_ACL)
 
 6194       command= 
"alter routine";
 
 6195     else if (want_access & GRANT_ACL)
 
 6197     my_error(ER_PROCACCESS_DENIED_ERROR, MYF(0),
 
 6198              command, user, host, table ? buff : 
"unknown");
 
 6219 bool check_routine_level_acl(THD *thd, 
const char *db, 
const char *name, 
 
 6222   bool no_routine_acl= 1;
 
 6224   Security_context *sctx= thd->security_ctx;
 
 6226   if ((grant_proc= routine_hash_search(sctx->priv_host,
 
 6227                                        sctx->get_ip()->ptr(), db,
 
 6230     no_routine_acl= !(grant_proc->privs & SHOW_PROC_ACLS);
 
 6232   return no_routine_acl;
 
 6240 ulong get_table_grant(THD *thd, 
TABLE_LIST *table)
 
 6243   Security_context *sctx= thd->security_ctx;
 
 6244   const char *db = table->db ? table->db : thd->db;
 
 6248 #ifdef EMBEDDED_LIBRARY 
 6251   grant_table= table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
 
 6252                                  db, sctx->priv_user, table->table_name, 0);
 
 6255   table->grant.
version=grant_version;
 
 6257     table->grant.
privilege|= grant_table->privs;
 
 6282 ulong get_column_grant(THD *thd, 
GRANT_INFO *grant,
 
 6283                        const char *db_name, 
const char *table_name,
 
 6284                        const char *field_name)
 
 6292   if (grant->
version != grant_version)
 
 6294     Security_context *sctx= thd->security_ctx;
 
 6296       table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
 
 6297                         db_name, sctx->priv_user,
 
 6299     grant->
version= grant_version;              
 
 6306     grant_column= column_hash_search(grant_table, field_name,
 
 6307                                      (uint) strlen(field_name));
 
 6309       priv= (grant->
privilege | grant_table->privs);
 
 6311       priv= (grant->
privilege | grant_table->privs | grant_column->rights);
 
 6320 static void add_user_option(
String *grant, ulong value, 
const char *name)
 
 6326     grant->append(name, strlen(name));
 
 6328     p=int10_to_str(value, buff, 10);
 
 6329     grant->append(buff,p-buff);
 
 6335 const char *command_array[]=
 
 6337   "SELECT", 
"INSERT", 
"UPDATE", 
"DELETE", 
"CREATE", 
"DROP", 
"RELOAD",
 
 6338   "SHUTDOWN", 
"PROCESS",
"FILE", 
"GRANT", 
"REFERENCES", 
"INDEX",
 
 6339   "ALTER", 
"SHOW DATABASES", 
"SUPER", 
"CREATE TEMPORARY TABLES",
 
 6340   "LOCK TABLES", 
"EXECUTE", 
"REPLICATION SLAVE", 
"REPLICATION CLIENT",
 
 6341   "CREATE VIEW", 
"SHOW VIEW", 
"CREATE ROUTINE", 
"ALTER ROUTINE",
 
 6342   "CREATE USER", 
"EVENT", 
"TRIGGER", 
"CREATE TABLESPACE" 
 6345 uint command_lengths[]=
 
 6347   6, 6, 6, 6, 6, 4, 6, 8, 7, 4, 5, 10, 5, 5, 14, 5, 23, 11, 7, 17, 18, 11, 9,
 
 6348   14, 13, 11, 5, 7, 17
 
 6351 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 6353 static int show_routine_grants(THD *thd, 
LEX_USER *lex_user, 
HASH *hash,
 
 6354                                const char *
type, 
int typelen,
 
 6355                                char *buff, 
int buffsize);
 
 6365 bool mysql_show_grants(THD *thd,
LEX_USER *lex_user)
 
 6374   DBUG_ENTER(
"mysql_show_grants");
 
 6376   LINT_INIT(acl_user);
 
 6379     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--skip-grant-tables");
 
 6386   acl_user= find_acl_user(lex_user->host.str, lex_user->user.str, TRUE);
 
 6392     my_error(ER_NONEXISTING_GRANT, MYF(0),
 
 6393              lex_user->user.str, lex_user->host.str);
 
 6399   field->max_length=1024;
 
 6400   strxmov(buff,
"Grants for ",lex_user->user.str,
"@",
 
 6401           lex_user->host.str,NullS);
 
 6402   field->item_name.
set(buff);
 
 6403   field_list.push_back(field);
 
 6405                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
 6415     String global(buff,
sizeof(buff),system_charset_info);
 
 6417     global.append(STRING_WITH_LEN(
"GRANT "));
 
 6419     want_access= acl_user->access;
 
 6420     if (test_all_bits(want_access, (GLOBAL_ACLS & ~ GRANT_ACL)))
 
 6421       global.append(STRING_WITH_LEN(
"ALL PRIVILEGES"));
 
 6422     else if (!(want_access & ~GRANT_ACL))
 
 6423       global.append(STRING_WITH_LEN(
"USAGE"));
 
 6427       ulong j,test_access= want_access & ~GRANT_ACL;
 
 6428       for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1)
 
 6430         if (test_access & j)
 
 6433             global.append(STRING_WITH_LEN(
", "));
 
 6435           global.append(command_array[counter],command_lengths[counter]);
 
 6439     global.append (STRING_WITH_LEN(
" ON *.* TO '"));
 
 6440     global.append(lex_user->user.str, lex_user->user.length,
 
 6441                   system_charset_info);
 
 6442     global.append (STRING_WITH_LEN(
"'@'"));
 
 6443     global.append(lex_user->host.str,lex_user->host.length,
 
 6444                   system_charset_info);
 
 6445     global.append (
'\'');
 
 6446 #if defined(HAVE_OPENSSL) 
 6447     if (acl_user->plugin.str == sha256_password_plugin_name.str)
 
 6449       global.append(STRING_WITH_LEN(
" IDENTIFIED BY PASSWORD '"));
 
 6450       global.append((
const char *) &acl_user->auth_string.str[0]);
 
 6451       global.append(
'\'');
 
 6457       char passwd_buff[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
 
 6458       if (acl_user->
salt_len == SCRAMBLE_LENGTH)
 
 6459         make_password_from_salt(passwd_buff, acl_user->
salt);
 
 6461         make_password_from_salt_323(passwd_buff, (ulong *) acl_user->
salt);
 
 6462       global.append(STRING_WITH_LEN(
" IDENTIFIED BY PASSWORD '"));
 
 6463       global.append(passwd_buff);
 
 6464       global.append(
'\'');
 
 6467     if (acl_user->ssl_type == SSL_TYPE_ANY)
 
 6468       global.append(STRING_WITH_LEN(
" REQUIRE SSL"));
 
 6469     else if (acl_user->ssl_type == SSL_TYPE_X509)
 
 6470       global.append(STRING_WITH_LEN(
" REQUIRE X509"));
 
 6471     else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
 
 6473       int ssl_options = 0;
 
 6474       global.append(STRING_WITH_LEN(
" REQUIRE "));
 
 6475       if (acl_user->x509_issuer)
 
 6478         global.append(STRING_WITH_LEN(
"ISSUER \'"));
 
 6479         global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
 
 6480         global.append(
'\'');
 
 6482       if (acl_user->x509_subject)
 
 6486         global.append(STRING_WITH_LEN(
"SUBJECT \'"));
 
 6487         global.append(acl_user->x509_subject,strlen(acl_user->x509_subject),
 
 6488                       system_charset_info);
 
 6489         global.append(
'\'');
 
 6491       if (acl_user->ssl_cipher)
 
 6495         global.append(STRING_WITH_LEN(
"CIPHER '"));
 
 6496         global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher),
 
 6497                       system_charset_info);
 
 6498         global.append(
'\'');
 
 6501     if ((want_access & GRANT_ACL) ||
 
 6502         (acl_user->user_resource.questions ||
 
 6503          acl_user->user_resource.updates ||
 
 6504          acl_user->user_resource.conn_per_hour ||
 
 6505          acl_user->user_resource.user_conn))
 
 6507       global.append(STRING_WITH_LEN(
" WITH"));
 
 6508       if (want_access & GRANT_ACL)
 
 6509         global.append(STRING_WITH_LEN(
" GRANT OPTION"));
 
 6510       add_user_option(&global, acl_user->user_resource.questions,
 
 6511                       "MAX_QUERIES_PER_HOUR");
 
 6512       add_user_option(&global, acl_user->user_resource.updates,
 
 6513                       "MAX_UPDATES_PER_HOUR");
 
 6514       add_user_option(&global, acl_user->user_resource.conn_per_hour,
 
 6515                       "MAX_CONNECTIONS_PER_HOUR");
 
 6516       add_user_option(&global, acl_user->user_resource.user_conn,
 
 6517                       "MAX_USER_CONNECTIONS");
 
 6519     protocol->prepare_for_resend();
 
 6520     protocol->
store(global.ptr(),global.length(),global.charset());
 
 6521     if (protocol->write())
 
 6529   for (counter=0 ; counter < acl_dbs.elements ; counter++)
 
 6531     const char *user, *host;
 
 6533     acl_db=dynamic_element(&acl_dbs,counter,
ACL_DB*);
 
 6534     if (!(user=acl_db->user))
 
 6536     if (!(host=acl_db->host.get_host()))
 
 6546     if (!strcmp(lex_user->user.str,user) &&
 
 6547         !my_strcasecmp(system_charset_info, lex_user->host.str, host))
 
 6549       want_access=acl_db->access;
 
 6552         String db(buff,
sizeof(buff),system_charset_info);
 
 6554         db.append(STRING_WITH_LEN(
"GRANT "));
 
 6556         if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL)))
 
 6557           db.append(STRING_WITH_LEN(
"ALL PRIVILEGES"));
 
 6558         else if (!(want_access & ~GRANT_ACL))
 
 6559           db.append(STRING_WITH_LEN(
"USAGE"));
 
 6563           ulong j,test_access= want_access & ~GRANT_ACL;
 
 6564           for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
 
 6566             if (test_access & j)
 
 6569                 db.append(STRING_WITH_LEN(
", "));
 
 6571               db.append(command_array[cnt],command_lengths[cnt]);
 
 6575         db.append (STRING_WITH_LEN(
" ON "));
 
 6576         append_identifier(thd, &db, acl_db->db, strlen(acl_db->db));
 
 6577         db.append (STRING_WITH_LEN(
".* TO '"));
 
 6578         db.append(lex_user->user.str, lex_user->user.length,
 
 6579                   system_charset_info);
 
 6580         db.append (STRING_WITH_LEN(
"'@'"));
 
 6582         db.append(host, strlen(host), system_charset_info);
 
 6584         if (want_access & GRANT_ACL)
 
 6585           db.append(STRING_WITH_LEN(
" WITH GRANT OPTION"));
 
 6586         protocol->prepare_for_resend();
 
 6587         protocol->
store(db.ptr(),db.length(),db.charset());
 
 6588         if (protocol->write())
 
 6598   for (index=0 ; index < column_priv_hash.records ; index++)
 
 6600     const char *user, *host;
 
 6602       my_hash_element(&column_priv_hash, index);
 
 6604     if (!(user=grant_table->user))
 
 6606     if (!(host= grant_table->host.get_host()))
 
 6616     if (!strcmp(lex_user->user.str,user) &&
 
 6617         !my_strcasecmp(system_charset_info, lex_user->host.str, host))
 
 6619       ulong table_access= grant_table->privs;
 
 6620       if ((table_access | grant_table->cols) != 0)
 
 6622         String global(buff, 
sizeof(buff), system_charset_info);
 
 6623         ulong test_access= (table_access | grant_table->cols) & ~GRANT_ACL;
 
 6626         global.append(STRING_WITH_LEN(
"GRANT "));
 
 6628         if (test_all_bits(table_access, (TABLE_ACLS & ~GRANT_ACL)))
 
 6629           global.append(STRING_WITH_LEN(
"ALL PRIVILEGES"));
 
 6630         else if (!test_access)
 
 6631           global.append(STRING_WITH_LEN(
"USAGE"));
 
 6638           for (counter= 0, j= SELECT_ACL; j <= TABLE_ACLS; counter++, j<<= 1)
 
 6640             if (test_access & j)
 
 6643                 global.append(STRING_WITH_LEN(
", "));
 
 6645               global.append(command_array[counter],command_lengths[counter]);
 
 6647               if (grant_table->cols)
 
 6650                 for (uint col_index=0 ;
 
 6651                      col_index < grant_table->hash_columns.records ;
 
 6655                     my_hash_element(&grant_table->hash_columns,col_index);
 
 6656                   if (grant_column->rights & j)
 
 6665                       if (table_access & j)
 
 6667                         global.append(STRING_WITH_LEN(
", "));
 
 6668                         global.append(command_array[counter],
 
 6669                                       command_lengths[counter]);
 
 6671                       global.append(STRING_WITH_LEN(
" ("));
 
 6674                       global.append(STRING_WITH_LEN(
", "));
 
 6675                     global.append(grant_column->column,
 
 6676                                   grant_column->key_length,
 
 6677                                   system_charset_info);
 
 6686         global.append(STRING_WITH_LEN(
" ON "));
 
 6687         append_identifier(thd, &global, grant_table->db,
 
 6688                           strlen(grant_table->db));
 
 6690         append_identifier(thd, &global, grant_table->tname,
 
 6691                           strlen(grant_table->tname));
 
 6692         global.append(STRING_WITH_LEN(
" TO '"));
 
 6693         global.append(lex_user->user.str, lex_user->user.length,
 
 6694                       system_charset_info);
 
 6695         global.append(STRING_WITH_LEN(
"'@'"));
 
 6697         global.append(host, strlen(host), system_charset_info);
 
 6698         global.append(
'\'');
 
 6699         if (table_access & GRANT_ACL)
 
 6700           global.append(STRING_WITH_LEN(
" WITH GRANT OPTION"));
 
 6701         protocol->prepare_for_resend();
 
 6702         protocol->
store(global.ptr(),global.length(),global.charset());
 
 6703         if (protocol->write())
 
 6712   if (show_routine_grants(thd, lex_user, &proc_priv_hash, 
 
 6713                           STRING_WITH_LEN(
"PROCEDURE"), buff, 
sizeof(buff)))
 
 6719   if (show_routine_grants(thd, lex_user, &func_priv_hash,
 
 6720                           STRING_WITH_LEN(
"FUNCTION"), buff, 
sizeof(buff)))
 
 6726   if (show_proxy_grants(thd, lex_user, buff, 
sizeof(buff)))
 
 6740 static int show_routine_grants(THD* thd, 
LEX_USER *lex_user, 
HASH *hash,
 
 6741                                const char *
type, 
int typelen,
 
 6742                                char *buff, 
int buffsize)
 
 6744   uint counter, 
index;
 
 6748   for (index=0 ; index < hash->records ; index++)
 
 6750     const char *user, *host;
 
 6753     if (!(user=grant_proc->user))
 
 6755     if (!(host= grant_proc->host.get_host()))
 
 6765     if (!strcmp(lex_user->user.str,user) &&
 
 6766         !my_strcasecmp(system_charset_info, lex_user->host.str, host))
 
 6768       ulong proc_access= grant_proc->privs;
 
 6769       if (proc_access != 0)
 
 6771         String global(buff, buffsize, system_charset_info);
 
 6772         ulong test_access= proc_access & ~GRANT_ACL;
 
 6775         global.append(STRING_WITH_LEN(
"GRANT "));
 
 6778           global.append(STRING_WITH_LEN(
"USAGE"));
 
 6785           for (counter= 0, j= SELECT_ACL; j <= PROC_ACLS; counter++, j<<= 1)
 
 6787             if (test_access & j)
 
 6790                 global.append(STRING_WITH_LEN(
", "));
 
 6792               global.append(command_array[counter],command_lengths[counter]);
 
 6796         global.append(STRING_WITH_LEN(
" ON "));
 
 6797         global.append(type,typelen);
 
 6799         append_identifier(thd, &global, grant_proc->db,
 
 6800                           strlen(grant_proc->db));
 
 6802         append_identifier(thd, &global, grant_proc->tname,
 
 6803                           strlen(grant_proc->tname));
 
 6804         global.append(STRING_WITH_LEN(
" TO '"));
 
 6805         global.append(lex_user->user.str, lex_user->user.length,
 
 6806                       system_charset_info);
 
 6807         global.append(STRING_WITH_LEN(
"'@'"));
 
 6809         global.append(host, strlen(host), system_charset_info);
 
 6810         global.append(
'\'');
 
 6811         if (proc_access & GRANT_ACL)
 
 6812           global.append(STRING_WITH_LEN(
" WITH GRANT OPTION"));
 
 6813         protocol->prepare_for_resend();
 
 6814         protocol->
store(global.ptr(),global.length(),global.charset());
 
 6815         if (protocol->write())
 
 6830 void get_privilege_desc(
char *
to, uint max_length, ulong access)
 
 6834   DBUG_ASSERT(max_length >= 30);                
 
 6839     for (pos=0 ; access ; pos++, access>>=1)
 
 6842           command_lengths[pos] + (uint) (to-start) < max_length)
 
 6844         to= strmov(to, command_array[pos]);
 
 6856 void get_mqh(
const char *user, 
const char *host, 
USER_CONN *uc)
 
 6862   if (initialized && (acl_user= find_acl_user(host,user, FALSE)))
 
 6863     uc->user_resources= acl_user->user_resource;
 
 6865     memset(&uc->user_resources, 0, 
sizeof(uc->user_resources));
 
 6893 #define GRANT_TABLES 6 
 6896 open_grant_tables(THD *thd, 
TABLE_LIST *tables, 
bool *transactional_tables)
 
 6898   DBUG_ENTER(
"open_grant_tables");
 
 6902     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--skip-grant-tables");
 
 6906   *transactional_tables= 
false;
 
 6909                          C_STRING_WITH_LEN(
"user"), 
"user", TL_WRITE);
 
 6910   (tables+1)->init_one_table(C_STRING_WITH_LEN(
"mysql"),
 
 6911                              C_STRING_WITH_LEN(
"db"), 
"db", TL_WRITE);
 
 6912   (tables+2)->init_one_table(C_STRING_WITH_LEN(
"mysql"),
 
 6913                              C_STRING_WITH_LEN(
"tables_priv"),
 
 6914                              "tables_priv", TL_WRITE);
 
 6915   (tables+3)->init_one_table(C_STRING_WITH_LEN(
"mysql"),
 
 6916                              C_STRING_WITH_LEN(
"columns_priv"),
 
 6917                              "columns_priv", TL_WRITE);
 
 6918   (tables+4)->init_one_table(C_STRING_WITH_LEN(
"mysql"),
 
 6919                              C_STRING_WITH_LEN(
"procs_priv"),
 
 6920                              "procs_priv", TL_WRITE);
 
 6921   (tables+5)->init_one_table(C_STRING_WITH_LEN(
"mysql"),
 
 6922                              C_STRING_WITH_LEN(
"proxies_priv"),
 
 6923                              "proxies_priv", TL_WRITE);
 
 6926   tables->next_local= tables->next_global= tables + 1;
 
 6927   (tables+1)->next_local= (tables+1)->next_global= tables + 2;
 
 6928   (tables+2)->next_local= (tables+2)->next_global= tables + 3;
 
 6929   (tables+3)->next_local= (tables+3)->next_global= tables + 4;
 
 6930   (tables+4)->next_local= (tables+4)->next_global= tables + 5;
 
 6932 #ifdef HAVE_REPLICATION 
 6937   if (thd->slave_thread && rpl_filter->is_on())
 
 6943     tables[0].updating= tables[1].updating= tables[2].updating=
 
 6944       tables[3].updating= tables[4].updating= tables[5].updating= 1;
 
 6945     if (!(thd->sp_runtime_ctx || rpl_filter->tables_ok(0, tables)))
 
 6947     tables[0].updating= tables[1].updating= tables[2].updating=
 
 6948       tables[3].updating= tables[4].updating= tables[5].updating= 0;
 
 6957   for (uint i= 0; i < GRANT_TABLES; ++
i)
 
 6958     *transactional_tables= (*transactional_tables ||
 
 6960                              tables[i].table->file->has_transactions()));
 
 6986 static int modify_grant_table(
TABLE *table, 
Field *host_field,
 
 6990   DBUG_ENTER(
"modify_grant_table");
 
 6995     store_record(table, 
record[1]);
 
 6996     host_field->store(user_to->host.str, user_to->host.length,
 
 6997                       system_charset_info);
 
 6998     user_field->store(user_to->user.str, user_to->user.length,
 
 6999                       system_charset_info);
 
 7000     if ((error= table->file->ha_update_row(table->record[1], 
 
 7001                                            table->record[0])) &&
 
 7002         error != HA_ERR_RECORD_IS_THE_SAME)
 
 7010     if ((error=table->file->ha_delete_row(table->record[0])))
 
 7049 static int handle_grant_table(
TABLE_LIST *tables, uint table_no, 
bool drop,
 
 7054   TABLE *table= tables[table_no].table;
 
 7055   Field *host_field= table->field[0];
 
 7056   Field *user_field= table->field[table_no && table_no != 5 ? 2 : 1];
 
 7057   char *host_str= user_from->host.str;
 
 7058   char *user_str= user_from->user.str;
 
 7061   uchar user_key[MAX_KEY_LENGTH];
 
 7062   uint key_prefix_length;
 
 7063   DBUG_ENTER(
"handle_grant_table");
 
 7064   THD *thd= current_thd;
 
 7066   table->use_all_columns();
 
 7078     DBUG_PRINT(
"info",(
"read table: '%s'  search: '%s'@'%s'",
 
 7079                        table->s->table_name.str, user_str, host_str));
 
 7080     host_field->store(host_str, user_from->host.length, system_charset_info);
 
 7081     user_field->store(user_str, user_from->user.length, system_charset_info);
 
 7083     if (!table->key_info)
 
 7085       my_error(ER_TABLE_CORRUPT, MYF(0), table->s->db.str,
 
 7086                table->s->table_name.str);
 
 7090     key_prefix_length= (table->key_info->key_part[0].store_length +
 
 7091                         table->key_info->key_part[1].store_length);
 
 7092     key_copy(user_key, table->record[0], table->key_info, key_prefix_length);
 
 7095                                                    user_key, (key_part_map)3,
 
 7096                                                    HA_READ_KEY_EXACT)))
 
 7098       if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
 
 7107       result= ((drop || user_to) &&
 
 7108                modify_grant_table(table, host_field, user_field, user_to)) ?
 
 7111     DBUG_PRINT(
"info",(
"read result: %d", result));
 
 7128       DBUG_PRINT(
"info",(
"scan table: '%s'  search: '%s'@'%s'",
 
 7129                          table->s->table_name.str, user_str, host_str));
 
 7131       while ((error= table->file->
ha_rnd_next(table->record[0])) != 
 
 7137           DBUG_PRINT(
"info",(
"scan error: %d", error));
 
 7140         if (! (host= get_field(thd->mem_root, host_field)))
 
 7142         if (! (user= get_field(thd->mem_root, user_field)))
 
 7148           DBUG_PRINT(
"loop",(
"scan fields: '%s'@'%s' '%s' '%s' '%s'",
 
 7150                              get_field(thd->mem_root, table->field[1]) ,
 
 7151                              get_field(thd->mem_root, table->field[3]) ,
 
 7152                              get_field(thd->mem_root,
 
 7153                                        table->field[4]) ));
 
 7156         if (strcmp(user_str, user) ||
 
 7157             my_strcasecmp(system_charset_info, host_str, host))
 
 7161         result= ((drop || user_to) &&
 
 7162                  modify_grant_table(table, host_field, user_field, user_to)) ?
 
 7163           -1 : result ? result : 1; 
 
 7165         if (! drop && ! user_to)
 
 7169       DBUG_PRINT(
"info",(
"scan result: %d", result));
 
 7173   DBUG_RETURN(result);
 
 7204 static int handle_grant_struct(
enum enum_acl_lists struct_no, 
bool drop,
 
 7221   HASH *grant_name_hash= NULL;
 
 7222   DBUG_ENTER(
"handle_grant_struct");
 
 7223   DBUG_PRINT(
"info",(
"scan struct: %u  search: '%s'@'%s'",
 
 7224                      struct_no, user_from->user.str, user_from->host.str));
 
 7232   switch (struct_no) {
 
 7234     elements= acl_users.elements;
 
 7237     elements= acl_dbs.elements;
 
 7239   case COLUMN_PRIVILEGES_HASH:
 
 7240     elements= column_priv_hash.records;
 
 7241     grant_name_hash= &column_priv_hash;
 
 7243   case PROC_PRIVILEGES_HASH:
 
 7244     elements= proc_priv_hash.records;
 
 7245     grant_name_hash= &proc_priv_hash;
 
 7247   case FUNC_PRIVILEGES_HASH:
 
 7248     elements= func_priv_hash.records;
 
 7249     grant_name_hash= &func_priv_hash;
 
 7251   case PROXY_USERS_ACL:
 
 7252     elements= acl_proxy_users.elements;
 
 7259     DBUG_PRINT(
"loop",(
"scan struct: %u  search    user: '%s'  host: '%s'",
 
 7260                        struct_no, user_from->user.str, user_from->host.str));
 
 7263   for (idx= 0; idx < elements; idx++)
 
 7268     switch (struct_no) {
 
 7270       acl_user= dynamic_element(&acl_users, idx, 
ACL_USER*);
 
 7271       user= acl_user->user;
 
 7272       host= acl_user->host.get_host();
 
 7276       acl_db= dynamic_element(&acl_dbs, idx, 
ACL_DB*);
 
 7278       host= acl_db->host.get_host();
 
 7281     case COLUMN_PRIVILEGES_HASH:
 
 7282     case PROC_PRIVILEGES_HASH:
 
 7283     case FUNC_PRIVILEGES_HASH:
 
 7284       grant_name= (
GRANT_NAME*) my_hash_element(grant_name_hash, idx);
 
 7285       user= grant_name->user;
 
 7286       host= grant_name->host.get_host();
 
 7289     case PROXY_USERS_ACL:
 
 7290       acl_proxy_user= dynamic_element(&acl_proxy_users, idx, 
ACL_PROXY_USER*);
 
 7291       user= acl_proxy_user->get_user();
 
 7292       host= acl_proxy_user->host.get_host();
 
 7296       MY_ASSERT_UNREACHABLE();
 
 7304     DBUG_PRINT(
"loop",(
"scan struct: %u  index: %u  user: '%s'  host: '%s'",
 
 7305                        struct_no, idx, user, host));
 
 7307     if (strcmp(user_from->user.str, user) ||
 
 7308         my_strcasecmp(system_charset_info, user_from->host.str, host))
 
 7314       switch ( struct_no ) {
 
 7316         delete_dynamic_element(&acl_users, idx);
 
 7329         delete_dynamic_element(&acl_dbs, idx);
 
 7334       case COLUMN_PRIVILEGES_HASH:
 
 7335       case PROC_PRIVILEGES_HASH:
 
 7336       case FUNC_PRIVILEGES_HASH:
 
 7341         if (acl_grant_name.
append(grant_name))
 
 7345       case PROXY_USERS_ACL:
 
 7346         delete_dynamic_element(&acl_proxy_users, idx);
 
 7354       switch ( struct_no ) {
 
 7356         acl_user->user= strdup_root(&global_acl_memory, user_to->user.str);
 
 7357         acl_user->host.
update_hostname(strdup_root(&global_acl_memory, user_to->host.str));
 
 7361         acl_db->user= strdup_root(&global_acl_memory, user_to->user.str);
 
 7362         acl_db->host.
update_hostname(strdup_root(&global_acl_memory, user_to->host.str));
 
 7365       case COLUMN_PRIVILEGES_HASH:
 
 7366       case PROC_PRIVILEGES_HASH:
 
 7367       case FUNC_PRIVILEGES_HASH:
 
 7372         if (acl_grant_name.
append(grant_name))
 
 7376       case PROXY_USERS_ACL:
 
 7377         acl_proxy_user->set_user(&global_acl_memory, user_to->user.str);
 
 7378         acl_proxy_user->host.
update_hostname((user_to->host.str && *user_to->host.str) ? 
 
 7379                                              strdup_root(&global_acl_memory, user_to->host.str) : NULL);
 
 7390   if (drop || user_to)
 
 7396     for (
int i= 0; i < acl_grant_name.elements(); ++
i)
 
 7398       grant_name= acl_grant_name.
at(i);
 
 7402         my_hash_delete(grant_name_hash, (uchar *) grant_name);
 
 7410         char *old_key= grant_name->hash_key;
 
 7411         size_t old_key_length= grant_name->key_length;
 
 7416         grant_name->set_user_details(user_to->host.str, grant_name->db,
 
 7417                                      user_to->user.str, grant_name->tname,
 
 7425         my_hash_update(grant_name_hash, (uchar*) grant_name, (uchar*) old_key,
 
 7432   DBUG_PRINT(
"loop",(
"scan struct: %u  result %d", struct_no, result));
 
 7435   DBUG_RETURN(result);
 
 7463 static int handle_grant_data(
TABLE_LIST *tables, 
bool drop,
 
 7469   DBUG_ENTER(
"handle_grant_data");
 
 7472   if ((found= handle_grant_table(tables, 0, drop, user_from, user_to)) < 0)
 
 7480     if (((ret= handle_grant_struct(USER_ACL, drop, user_from, user_to) > 0) &&
 
 7485       if (! drop && ! user_to)
 
 7496   if ((found= handle_grant_table(tables, 1, drop, user_from, user_to)) < 0)
 
 7504     if ((((ret= handle_grant_struct(DB_ACL, drop, user_from, user_to) > 0) &&
 
 7505           ! result) || found) && ! result)
 
 7509       if (! drop && ! user_to)
 
 7520   if ((found= handle_grant_table(tables, 4, drop, user_from, user_to)) < 0)
 
 7528     if ((((ret= handle_grant_struct(PROC_PRIVILEGES_HASH, drop, user_from,
 
 7529                                     user_to) > 0) && ! result) || found) &&
 
 7534       if (! drop && ! user_to)
 
 7543     if ((((ret= handle_grant_struct(FUNC_PRIVILEGES_HASH, drop, user_from,
 
 7544                                     user_to) > 0) && ! result) || found) &&
 
 7549       if (! drop && ! user_to)
 
 7560   if ((found= handle_grant_table(tables, 2, drop, user_from, user_to)) < 0)
 
 7567     if (found && ! result)
 
 7571       if (! drop && ! user_to)
 
 7576     if ((found= handle_grant_table(tables, 3, drop, user_from, user_to)) < 0)
 
 7584       if ((((ret= handle_grant_struct(COLUMN_PRIVILEGES_HASH, drop, user_from,
 
 7585                                       user_to) > 0) && ! result) || found) &&
 
 7594   if (tables[5].table)
 
 7596     if ((found= handle_grant_table(tables, 5, drop, user_from, user_to)) < 0)
 
 7604       if (((ret= handle_grant_struct(PROXY_USERS_ACL, drop, user_from, user_to) > 0)
 
 7605            && !result) || found)
 
 7612   DBUG_RETURN(result);
 
 7628 void append_user(THD *thd, 
String *str, 
LEX_USER *user, 
bool comma= 
true,
 
 7631   String from_user(user->user.str, user->user.length, system_charset_info);
 
 7632   String from_plugin(user->plugin.str, user->plugin.length, system_charset_info);
 
 7633   String from_auth(user->auth.str, user->auth.length, system_charset_info);
 
 7634   String from_host(user->host.str, user->host.length, system_charset_info);
 
 7639   str->append(STRING_WITH_LEN(
"@"));
 
 7644     if (user->plugin.str && (user->plugin.length > 0) &&
 
 7645         memcmp(user->plugin.str, native_password_plugin_name.str,
 
 7646                user->plugin.length) &&
 
 7647         memcmp(user->plugin.str, old_password_plugin_name.str,
 
 7648                user->plugin.length))
 
 7655       str->append(STRING_WITH_LEN(
" IDENTIFIED WITH "));
 
 7658       if (user->auth.str && (user->auth.length > 0))
 
 7660         str->append(STRING_WITH_LEN(
" AS "));
 
 7664     else if (user->password.str)
 
 7666       str->append(STRING_WITH_LEN(
" IDENTIFIED BY PASSWORD '"));
 
 7667       if (user->uses_identified_by_password_clause)
 
 7669         str->append(user->password.str, user->password.length);
 
 7679         if (thd->variables.old_passwords == 0)
 
 7687           char tmp[SCRAMBLED_PASSWORD_CHAR_LENGTH + 1];
 
 7688           my_make_scrambled_password_sha1(tmp, user->password.str,
 
 7689                                           user->password.length);
 
 7700           str->append(
"<secret>");
 
 7708 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 7727   LEX_USER *user_name, *tmp_user_name;
 
 7730   bool some_users_created= FALSE;
 
 7731   bool save_binlog_row_based;
 
 7732   bool transactional_tables;
 
 7733   DBUG_ENTER(
"mysql_create_user");
 
 7740   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 7741     thd->clear_current_stmt_binlog_format_row();
 
 7744   if ((result= open_grant_tables(thd, tables, &transactional_tables)))
 
 7747     DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 7748     if (save_binlog_row_based)
 
 7749       thd->set_current_stmt_binlog_format_row();
 
 7750     DBUG_RETURN(result != 1);
 
 7756   while ((tmp_user_name= user_list++))
 
 7773     if (user_name->plugin.length == 0 && user_name->uses_identified_with_clause)
 
 7775       user_name->plugin.str= default_auth_plugin_name.str;
 
 7776       user_name->plugin.length= default_auth_plugin_name.length;
 
 7783     if (handle_grant_data(tables, 0, user_name, NULL))
 
 7785       append_user(thd, &wrong_users, user_name, wrong_users.length() > 0,
 
 7791     if (replace_user_table(thd, tables[0].table, user_name, 0, 0, 1, 0))
 
 7793       append_user(thd, &wrong_users, user_name, wrong_users.length() > 0,
 
 7799     some_users_created= TRUE;
 
 7805     my_error(ER_CANNOT_USER, MYF(0), 
"CREATE USER", wrong_users.c_ptr_safe());
 
 7807   if (some_users_created)
 
 7809     if (!thd->rewritten_query.length())
 
 7810       result|= write_bin_log(thd, 
false, thd->query(), thd->query_length(),
 
 7811                              transactional_tables);
 
 7813       result|= write_bin_log(thd, 
false,
 
 7814                              thd->rewritten_query.c_ptr_safe(),
 
 7815                              thd->rewritten_query.length(),
 
 7816                              transactional_tables);
 
 7821   result|= acl_trans_commit_and_close_tables(thd);
 
 7824   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 7825   if (save_binlog_row_based)
 
 7826     thd->set_current_stmt_binlog_format_row();
 
 7827   DBUG_RETURN(result);
 
 7848   LEX_USER *user_name, *tmp_user_name;
 
 7851   bool some_users_deleted= FALSE;
 
 7852   sql_mode_t old_sql_mode= thd->variables.sql_mode;
 
 7853   bool save_binlog_row_based;
 
 7854   bool transactional_tables;
 
 7855   DBUG_ENTER(
"mysql_drop_user");
 
 7862   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 7863     thd->clear_current_stmt_binlog_format_row();
 
 7866   if ((result= open_grant_tables(thd, tables, &transactional_tables)))
 
 7869     DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 7870     if (save_binlog_row_based)
 
 7871       thd->set_current_stmt_binlog_format_row();
 
 7872     DBUG_RETURN(result != 1);
 
 7875   thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
 
 7880   while ((tmp_user_name= user_list++))
 
 7887     if (handle_grant_data(tables, 1, user_name, NULL) <= 0)
 
 7889       append_user(thd, &wrong_users, user_name, wrong_users.length() > 0, FALSE);
 
 7893     some_users_deleted= TRUE;
 
 7897   rebuild_check_host();
 
 7902     my_error(ER_CANNOT_USER, MYF(0), 
"DROP USER", wrong_users.c_ptr_safe());
 
 7904   if (some_users_deleted)
 
 7905     result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length(),
 
 7906                             transactional_tables);
 
 7910   result|= acl_trans_commit_and_close_tables(thd);
 
 7912   thd->variables.sql_mode= old_sql_mode;
 
 7914   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 7915   if (save_binlog_row_based)
 
 7916     thd->set_current_stmt_binlog_format_row();
 
 7917   DBUG_RETURN(result);
 
 7938   LEX_USER *user_from, *tmp_user_from;
 
 7942   bool some_users_renamed= FALSE;
 
 7943   bool save_binlog_row_based;
 
 7944   bool transactional_tables;
 
 7945   DBUG_ENTER(
"mysql_rename_user");
 
 7952   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 7953     thd->clear_current_stmt_binlog_format_row();
 
 7956   if ((result= open_grant_tables(thd, tables, &transactional_tables)))
 
 7959     DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 7960     if (save_binlog_row_based)
 
 7961       thd->set_current_stmt_binlog_format_row();
 
 7962     DBUG_RETURN(result != 1);
 
 7968   while ((tmp_user_from= user_list++))
 
 7975     tmp_user_to= user_list++;
 
 7981     DBUG_ASSERT(user_to != 0); 
 
 7987     if (handle_grant_data(tables, 0, user_to, NULL) ||
 
 7988         handle_grant_data(tables, 0, user_from, user_to) <= 0)
 
 7990       append_user(thd, &wrong_users, user_from, wrong_users.length() > 0, FALSE);
 
 7994     some_users_renamed= TRUE;
 
 7998   rebuild_check_host();
 
 8003     my_error(ER_CANNOT_USER, MYF(0), 
"RENAME USER", wrong_users.c_ptr_safe());
 
 8005   if (some_users_renamed)
 
 8006     result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length(),
 
 8007                             transactional_tables);
 
 8011   result|= acl_trans_commit_and_close_tables(thd);
 
 8014   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 8015   if (save_binlog_row_based)
 
 8016     thd->set_current_stmt_binlog_format_row();
 
 8017   DBUG_RETURN(result);
 
 8038   LEX_USER *user_from, *tmp_user_from;
 
 8042   bool some_passwords_expired= 
false;
 
 8043   bool save_binlog_row_based;
 
 8044   DBUG_ENTER(
"mysql_user_password_expire");
 
 8048     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--skip-grant-tables");
 
 8053 #ifdef HAVE_REPLICATION 
 8058   if (thd->slave_thread && rpl_filter->is_on())
 
 8066     if (!(thd->sp_runtime_ctx || rpl_filter->tables_ok(0, &tables)))
 
 8070   if (!(table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT)))
 
 8073   if (!table->key_info)
 
 8075     my_error(ER_TABLE_CORRUPT, MYF(0), table->s->db.str,
 
 8076              table->s->table_name.str);
 
 8085   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 8086     thd->clear_current_stmt_binlog_format_row();
 
 8091   while ((tmp_user_from= user_list++))
 
 8099       append_user(thd, &wrong_users, tmp_user_from, wrong_users.length() > 0,
 
 8105     if (!(acl_user= find_acl_user(user_from->host.str,
 
 8106                                    user_from->user.str, TRUE)))
 
 8109       append_user(thd, &wrong_users, user_from, wrong_users.length() > 0,
 
 8115     if (!auth_plugin_supports_expiration(acl_user->plugin.str))
 
 8118       append_user(thd, &wrong_users, user_from, wrong_users.length() > 0,
 
 8125     enum mysql_user_table_field password_field= MYSQL_USER_FIELD_PASSWORD;
 
 8126     if (update_user_table(thd, table,
 
 8127                           acl_user->host.get_host() ?
 
 8128                           acl_user->host.get_host() : 
"",
 
 8129                           acl_user->user ? acl_user->user : 
"",
 
 8130                           NULL, 0, password_field, 
true, 
false))
 
 8133       append_user(thd, &wrong_users, user_from, wrong_users.length() > 0,
 
 8138     acl_user->password_expired= 
true;
 
 8139     some_passwords_expired= 
true;
 
 8142   acl_cache->clear(1);                          
 
 8146     my_error(ER_CANNOT_USER, MYF(0), 
"ALTER USER", wrong_users.c_ptr_safe());
 
 8148   if (!result && some_passwords_expired)
 
 8150     const char *
query= thd->rewritten_query.length() ?
 
 8151       thd->rewritten_query.c_ptr_safe() : thd->query();
 
 8152     const size_t query_length= thd->rewritten_query.length() ?
 
 8153       thd->rewritten_query.length() : thd->query_length();
 
 8154     result= (write_bin_log(thd, 
false, query, query_length,
 
 8155                            table->file->has_transactions()) != 0);
 
 8160   result|= acl_trans_commit_and_close_tables(thd);
 
 8163   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 8164   if (save_binlog_row_based)
 
 8165     thd->set_current_stmt_binlog_format_row();
 
 8166   DBUG_RETURN(result);
 
 8186   uint counter, revoked, is_proc;
 
 8190   bool save_binlog_row_based;
 
 8191   bool transactional_tables;
 
 8192   DBUG_ENTER(
"mysql_revoke_all");
 
 8199   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 8200     thd->clear_current_stmt_binlog_format_row();
 
 8202   if ((result= open_grant_tables(thd, tables, &transactional_tables)))
 
 8205     DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 8206     if (save_binlog_row_based)
 
 8207       thd->set_current_stmt_binlog_format_row();
 
 8208     DBUG_RETURN(result != 1);
 
 8216   while ((tmp_lex_user= user_list++))
 
 8223     if (!find_acl_user(lex_user->host.str, lex_user->user.str, TRUE))
 
 8229     if (replace_user_table(thd, tables[0].table,
 
 8230                            lex_user, ~(ulong) 0, 1, 0, 0))
 
 8244       for (counter= 0, revoked= 0 ; counter < acl_dbs.elements ; )
 
 8246         const char *user,*host;
 
 8248         acl_db=dynamic_element(&acl_dbs,counter,
ACL_DB*);
 
 8249         if (!(user=acl_db->user))
 
 8251         if (!(host=acl_db->host.get_host()))
 
 8254         if (!strcmp(lex_user->user.str,user) &&
 
 8255             !strcmp(lex_user->host.str, host))
 
 8257           if (!replace_db_table(tables[1].table, acl_db->db, *lex_user,
 
 8276       for (counter= 0, revoked= 0 ; counter < column_priv_hash.records ; )
 
 8278         const char *user,*host;
 
 8280           (
GRANT_TABLE*) my_hash_element(&column_priv_hash, counter);
 
 8281         if (!(user=grant_table->user))
 
 8283         if (!(host=grant_table->host.get_host()))
 
 8286         if (!strcmp(lex_user->user.str,user) &&
 
 8287             !strcmp(lex_user->host.str, host))
 
 8289           if (replace_table_table(thd,grant_table,tables[2].table,*lex_user,
 
 8298             if (!grant_table->cols)
 
 8304             if (!replace_column_table(grant_table,tables[3].table, *lex_user,
 
 8321     for (is_proc=0; is_proc<2; is_proc++) 
do {
 
 8322       HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
 
 8323       for (counter= 0, revoked= 0 ; counter < hash->records ; )
 
 8325         const char *user,*host;
 
 8327         if (!(user=grant_proc->user))
 
 8329         if (!(host=grant_proc->host.get_host()))
 
 8332         if (!strcmp(lex_user->user.str,user) &&
 
 8333             !strcmp(lex_user->host.str, host))
 
 8335           if (replace_routine_table(thd,grant_proc,tables[4].table,*lex_user,
 
 8354     my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
 
 8361       write_bin_log(thd, FALSE, thd->query(), thd->query_length(),
 
 8362                     transactional_tables);
 
 8367   result|= acl_trans_commit_and_close_tables(thd);
 
 8370   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 8371   if (save_binlog_row_based)
 
 8372     thd->set_current_stmt_binlog_format_row();
 
 8374   DBUG_RETURN(result);
 
 8398   virtual bool handle_condition(THD *thd,
 
 8400                                 const char* sqlstate,
 
 8401                                 Sql_condition::enum_warning_level 
level,
 
 8405   bool has_errors() { 
return is_grave; }
 
 8412 Silence_routine_definer_errors::handle_condition(
 
 8416   Sql_condition::enum_warning_level 
level,
 
 8421   if (level == Sql_condition::WARN_LEVEL_ERROR)
 
 8425       case ER_NONEXISTING_PROC_GRANT:
 
 8427         push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
 
 8456 bool sp_revoke_privileges(THD *thd, 
const char *sp_db, 
const char *
sp_name,
 
 8459   uint counter, revoked;
 
 8462   HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
 
 8464   bool save_binlog_row_based;
 
 8466   DBUG_ENTER(
"sp_revoke_privileges");
 
 8468   if ((result= open_grant_tables(thd, tables, ¬_used)))
 
 8469     DBUG_RETURN(result != 1);
 
 8472   thd->push_internal_handler(&error_handler);
 
 8482   if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
 
 8483     thd->clear_current_stmt_binlog_format_row();
 
 8488     for (counter= 0, revoked= 0 ; counter < hash->records ; )
 
 8491       if (!my_strcasecmp(&my_charset_utf8_bin, grant_proc->db, sp_db) &&
 
 8492           !my_strcasecmp(system_charset_info, grant_proc->tname, sp_name))
 
 8495         lex_user.user.str= grant_proc->user;
 
 8496         lex_user.user.length= strlen(grant_proc->user);
 
 8497         lex_user.host.str= (
char*) (grant_proc->host.get_host() ?
 
 8498           grant_proc->host.get_host() : 
"");
 
 8499         lex_user.host.length= grant_proc->host.get_host() ?
 
 8500           strlen(grant_proc->host.get_host()) : 0;
 
 8502         if (replace_routine_table(thd,grant_proc,tables[4].table,lex_user,
 
 8503                                   grant_proc->db, grant_proc->tname,
 
 8504                                   is_proc, ~(ulong)0, 1) == 0)
 
 8517   result= acl_trans_commit_and_close_tables(thd);
 
 8519   thd->pop_internal_handler();
 
 8522   DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
 
 8523   if (save_binlog_row_based)
 
 8524     thd->set_current_stmt_binlog_format_row();
 
 8526   DBUG_RETURN(error_handler.has_errors() || result);
 
 8543 bool sp_grant_privileges(THD *thd, 
const char *sp_db, 
const char *sp_name,
 
 8546   Security_context *sctx= thd->security_ctx;
 
 8552   Dummy_error_handler error_handler;
 
 8553   DBUG_ENTER(
"sp_grant_privileges");
 
 8558   combo->user.str= sctx->user;
 
 8562   if ((au= find_acl_user(combo->host.str=(
char*)sctx->host_or_ip,combo->user.str,FALSE)))
 
 8564   if ((au= find_acl_user(combo->host.str=(
char*)sctx->get_host()->ptr(),
 
 8565                          combo->user.str,FALSE)))
 
 8567   if ((au= find_acl_user(combo->host.str=(
char*)sctx->get_ip()->ptr(),
 
 8568                          combo->user.str,FALSE)))
 
 8570   if((au= find_acl_user(combo->host.str=(
char*)
"%", combo->user.str, FALSE)))
 
 8582   tables->db= (
char*)sp_db;
 
 8583   tables->table_name= tables->alias= (
char*)sp_name;
 
 8585   thd->make_lex_string(&combo->user,
 
 8586                        combo->user.str, strlen(combo->user.str), 0);
 
 8587   thd->make_lex_string(&combo->host,
 
 8588                        combo->host.str, strlen(combo->host.str), 0);
 
 8590   combo->password= empty_lex_str;
 
 8591   combo->plugin= empty_lex_str;
 
 8592   combo->auth= empty_lex_str;
 
 8593   combo->uses_identified_by_clause= 
false;
 
 8594   combo->uses_identified_with_clause= 
false;
 
 8595   combo->uses_identified_by_password_clause= 
false;
 
 8596   combo->uses_authentication_string_clause= 
false;
 
 8598   if (user_list.push_back(combo))
 
 8601   thd->lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
 
 8602   thd->lex->ssl_cipher= thd->lex->x509_subject= thd->lex->x509_issuer= 0;
 
 8603   memset(&thd->lex->mqh, 0, 
sizeof(thd->lex->mqh));
 
 8609   thd->push_internal_handler(&error_handler);
 
 8610   result= mysql_routine_grant(thd, tables, is_proc, user_list,
 
 8611                               DEFAULT_CREATE_PROC_ACLS, FALSE, FALSE);
 
 8612   thd->pop_internal_handler();
 
 8613   DBUG_RETURN(result);
 
 8630 acl_find_proxy_user(
const char *user, 
const char *host, 
const char *ip, 
 
 8631                     const char *authenticated_as, 
bool *proxy_used)
 
 8635   DBUG_ENTER(
"acl_find_proxy_user");
 
 8636   DBUG_PRINT(
"info", (
"user=%s host=%s ip=%s authenticated_as=%s",
 
 8637                       user, host, ip, authenticated_as));
 
 8639   if (!strcmp(authenticated_as, user))
 
 8641     DBUG_PRINT (
"info", (
"user is the same as authenticated_as"));
 
 8646   for (i=0; i < acl_proxy_users.elements; i++)
 
 8650     if (proxy->matches(host, user, ip, authenticated_as))
 
 8659 acl_check_proxy_grant_access(THD *thd, 
const char *host, 
const char *user,
 
 8662   DBUG_ENTER(
"acl_check_proxy_grant_access");
 
 8663   DBUG_PRINT(
"info", (
"user=%s host=%s with_grant=%d", user, host, 
 
 8667     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), 
"--skip-grant-tables");
 
 8672   if (thd->slave_thread)
 
 8674     DBUG_PRINT(
"info", (
"replication slave"));
 
 8690   if (!strcmp(thd->security_ctx->priv_user, user) &&
 
 8691       !my_strcasecmp(system_charset_info, host,
 
 8692                      thd->security_ctx->priv_host))
 
 8694     DBUG_PRINT(
"info", (
"strcmp (%s, %s) my_casestrcmp (%s, %s) equal", 
 
 8695                         thd->security_ctx->priv_user, user,
 
 8696                         host, thd->security_ctx->priv_host));
 
 8701   for (uint i=0; i < acl_proxy_users.elements; i++)
 
 8705     if (proxy->matches(thd->security_ctx->get_host()->ptr(),
 
 8706                        thd->security_ctx->user,
 
 8707                        thd->security_ctx->get_ip()->ptr(),
 
 8709         proxy->get_with_grant())
 
 8711       DBUG_PRINT(
"info", (
"found"));
 
 8716   my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
 
 8717            thd->security_ctx->user,
 
 8718            thd->security_ctx->host_or_ip);
 
 8724 show_proxy_grants(THD *thd, 
LEX_USER *user, 
char *buff, 
size_t buffsize)
 
 8729   for (uint i=0; i < acl_proxy_users.elements; i++)
 
 8733     if (proxy->granted_on(user->host.str, user->user.str))
 
 8735       String global(buff, buffsize, system_charset_info);
 
 8737       proxy->print_grant(&global);
 
 8738       protocol->prepare_for_resend();
 
 8739       protocol->
store(global.ptr(), global.length(), global.charset());
 
 8740       if (protocol->write())
 
 8754 int wild_case_compare(
CHARSET_INFO *cs, 
const char *str,
const char *wildstr)
 
 8757   DBUG_ENTER(
"wild_case_compare");
 
 8758   DBUG_PRINT(
"enter",(
"str: '%s'  wildstr: '%s'",str,wildstr));
 
 8761     while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
 
 8763       if (*wildstr == wild_prefix && wildstr[1])
 
 8765       if (my_toupper(cs, *wildstr++) !=
 
 8766           my_toupper(cs, *str++)) DBUG_RETURN(1);
 
 8768     if (! *wildstr ) DBUG_RETURN (*str != 0);
 
 8769     if (*wildstr++ == wild_one)
 
 8771       if (! *str++) DBUG_RETURN (1);    
 
 8775       if (!*wildstr) DBUG_RETURN(0);            
 
 8776       flag=(*wildstr != wild_many && *wildstr != wild_one);
 
 8782           if ((cmp= *wildstr) == wild_prefix && wildstr[1])
 
 8784           cmp=my_toupper(cs, cmp);
 
 8785           while (*str && my_toupper(cs, *str) != cmp)
 
 8787           if (!*str) DBUG_RETURN (1);
 
 8789         if (wild_case_compare(cs, str,wildstr) == 0) DBUG_RETURN (0);
 
 8794   DBUG_RETURN (*str != 
'\0');
 
 8798 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 8799 static bool update_schema_privilege(THD *thd, 
TABLE *table, 
char *buff,
 
 8800                                     const char* db, 
const char* t_name,
 
 8801                                     const char* column, uint col_length,
 
 8802                                     const char *priv, uint priv_length,
 
 8803                                     const char* is_grantable)
 
 8807   restore_record(table, s->default_values);
 
 8808   table->field[0]->store(buff, (uint) strlen(buff), cs);
 
 8809   table->field[1]->store(STRING_WITH_LEN(
"def"), cs);
 
 8811     table->field[i++]->store(db, (uint) strlen(db), cs);
 
 8813     table->field[i++]->store(t_name, (uint) strlen(t_name), cs);
 
 8815     table->field[i++]->store(column, col_length, cs);
 
 8816   table->field[i++]->store(priv, priv_length, cs);
 
 8817   table->field[
i]->store(is_grantable, strlen(is_grantable), cs);
 
 8818   return schema_table_store_record(thd, table);
 
 8823 int fill_schema_user_privileges(THD *thd, 
TABLE_LIST *tables, 
Item *cond)
 
 8825 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 8831   TABLE *table= tables->table;
 
 8832   bool no_global_access= 
check_access(thd, SELECT_ACL, 
"mysql",
 
 8834   char *curr_host= thd->security_ctx->priv_host_name();
 
 8835   DBUG_ENTER(
"fill_schema_user_privileges");
 
 8841   for (counter=0 ; counter < acl_users.elements ; counter++)
 
 8843     const char *user,*host, *is_grantable=
"YES";
 
 8844     acl_user=dynamic_element(&acl_users,counter,
ACL_USER*);
 
 8845     if (!(user=acl_user->user))
 
 8847     if (!(host=acl_user->host.get_host()))
 
 8850     if (no_global_access &&
 
 8851         (strcmp(thd->security_ctx->priv_user, user) ||
 
 8852          my_strcasecmp(system_charset_info, curr_host, host)))
 
 8855     want_access= acl_user->access;
 
 8856     if (!(want_access & GRANT_ACL))
 
 8859     strxmov(buff,
"'",user,
"'@'",host,
"'",NullS);
 
 8860     if (!(want_access & ~GRANT_ACL))
 
 8862       if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
 
 8863                                   STRING_WITH_LEN(
"USAGE"), is_grantable))
 
 8872       ulong j,test_access= want_access & ~GRANT_ACL;
 
 8873       for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1)
 
 8875         if (test_access & j)
 
 8877           if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0, 
 
 8878                                       command_array[priv_id],
 
 8879                                       command_lengths[priv_id], is_grantable))
 
 8898 int fill_schema_schema_privileges(THD *thd, 
TABLE_LIST *tables, 
Item *cond)
 
 8900 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 8906   TABLE *table= tables->table;
 
 8907   bool no_global_access= 
check_access(thd, SELECT_ACL, 
"mysql",
 
 8909   char *curr_host= thd->security_ctx->priv_host_name();
 
 8910   DBUG_ENTER(
"fill_schema_schema_privileges");
 
 8916   for (counter=0 ; counter < acl_dbs.elements ; counter++)
 
 8918     const char *user, *host, *is_grantable=
"YES";
 
 8920     acl_db=dynamic_element(&acl_dbs,counter,
ACL_DB*);
 
 8921     if (!(user=acl_db->user))
 
 8923     if (!(host=acl_db->host.get_host()))
 
 8926     if (no_global_access &&
 
 8927         (strcmp(thd->security_ctx->priv_user, user) ||
 
 8928          my_strcasecmp(system_charset_info, curr_host, host)))
 
 8931     want_access=acl_db->access;
 
 8934       if (!(want_access & GRANT_ACL))
 
 8938       strxmov(buff,
"'",user,
"'@'",host,
"'",NullS);
 
 8939       if (!(want_access & ~GRANT_ACL))
 
 8941         if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0,
 
 8942                                     0, STRING_WITH_LEN(
"USAGE"), is_grantable))
 
 8951         ulong j,test_access= want_access & ~GRANT_ACL;
 
 8952         for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
 
 8953           if (test_access & j)
 
 8955             if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, 0,
 
 8956                                         command_array[cnt], command_lengths[cnt],
 
 8976 int fill_schema_table_privileges(THD *thd, 
TABLE_LIST *tables, 
Item *cond)
 
 8978 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 8982   TABLE *table= tables->table;
 
 8983   bool no_global_access= 
check_access(thd, SELECT_ACL, 
"mysql",
 
 8985   char *curr_host= thd->security_ctx->priv_host_name();
 
 8986   DBUG_ENTER(
"fill_schema_table_privileges");
 
 8990   for (index=0 ; index < column_priv_hash.records ; index++)
 
 8992     const char *user, *host, *is_grantable= 
"YES";
 
 8995     if (!(user=grant_table->user))
 
 8997     if (!(host= grant_table->host.get_host()))
 
 9000     if (no_global_access &&
 
 9001         (strcmp(thd->security_ctx->priv_user, user) ||
 
 9002          my_strcasecmp(system_charset_info, curr_host, host)))
 
 9005     ulong table_access= grant_table->privs;
 
 9008       ulong test_access= table_access & ~GRANT_ACL;
 
 9013       if (!test_access && grant_table->cols)
 
 9015       if (!(table_access & GRANT_ACL))
 
 9018       strxmov(buff, 
"'", user, 
"'@'", host, 
"'", NullS);
 
 9021         if (update_schema_privilege(thd, table, buff, grant_table->db,
 
 9022                                     grant_table->tname, 0, 0,
 
 9023                                     STRING_WITH_LEN(
"USAGE"), is_grantable))
 
 9033         for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1)
 
 9035           if (test_access & j)
 
 9037             if (update_schema_privilege(thd, table, buff, grant_table->db,
 
 9038                                         grant_table->tname, 0, 0,
 
 9040                                         command_lengths[cnt], is_grantable))
 
 9060 int fill_schema_column_privileges(THD *thd, 
TABLE_LIST *tables, 
Item *cond)
 
 9062 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 9066   TABLE *table= tables->table;
 
 9067   bool no_global_access= 
check_access(thd, SELECT_ACL, 
"mysql",
 
 9069   char *curr_host= thd->security_ctx->priv_host_name();
 
 9070   DBUG_ENTER(
"fill_schema_table_privileges");
 
 9074   for (index=0 ; index < column_priv_hash.records ; index++)
 
 9076     const char *user, *host, *is_grantable= 
"YES";
 
 9079     if (!(user=grant_table->user))
 
 9081     if (!(host= grant_table->host.get_host()))
 
 9084     if (no_global_access &&
 
 9085         (strcmp(thd->security_ctx->priv_user, user) ||
 
 9086          my_strcasecmp(system_charset_info, curr_host, host)))
 
 9089     ulong table_access= grant_table->cols;
 
 9090     if (table_access != 0)
 
 9092       if (!(grant_table->privs & GRANT_ACL))
 
 9095       ulong test_access= table_access & ~GRANT_ACL;
 
 9096       strxmov(buff, 
"'", user, 
"'@'", host, 
"'", NullS);
 
 9103         for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1)
 
 9105           if (test_access & j)
 
 9107             for (uint col_index=0 ;
 
 9108                  col_index < grant_table->hash_columns.records ;
 
 9112                 my_hash_element(&grant_table->hash_columns,col_index);
 
 9113               if ((grant_column->rights & j) && (table_access & j))
 
 9115                 if (update_schema_privilege(thd, table, buff, grant_table->db,
 
 9117                                             grant_column->column,
 
 9118                                             grant_column->key_length,
 
 9120                                             command_lengths[cnt], is_grantable))
 
 9142 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 9154 void fill_effective_table_privileges(THD *thd, 
GRANT_INFO *grant,
 
 9155                                      const char *db, 
const char *table)
 
 9157   Security_context *sctx= thd->security_ctx;
 
 9158   DBUG_ENTER(
"fill_effective_table_privileges");
 
 9159   DBUG_PRINT(
"enter", (
"Host: '%s', Ip: '%s', User: '%s', table: `%s`.`%s`",
 
 9160                        sctx->priv_host, (sctx->get_ip()->length() ?
 
 9161                        sctx->get_ip()->ptr() : 
"(NULL)"),
 
 9162                        (sctx->priv_user ? sctx->priv_user : 
"(NULL)"),
 
 9167     DBUG_PRINT(
"info", (
"skip grants"));
 
 9169     DBUG_PRINT(
"info", (
"privilege 0x%lx", grant->
privilege));
 
 9176   if (!sctx->priv_user)
 
 9178     DBUG_PRINT(
"info", (
"privilege 0x%lx", grant->
privilege));
 
 9183   grant->
privilege|= acl_get(sctx->get_host()->ptr(), sctx->get_ip()->ptr(),
 
 9184                              sctx->priv_user, db, 0);
 
 9188   if (grant->
version != grant_version)
 
 9191       table_hash_search(sctx->get_host()->ptr(), sctx->get_ip()->ptr(), db,
 
 9194     grant->
version= grant_version;              
 
 9202   DBUG_PRINT(
"info", (
"privilege 0x%lx", grant->
privilege));
 
 9212 bool check_routine_level_acl(THD *thd, 
const char *db, 
const char *name,
 
 9235 static uint m_registry_array_size= 0;
 
 9245   DBUG_ASSERT(m_registry_array_size < array_elements(registry_array));
 
 9248   registry_array[m_registry_array_size].m_name= 
name;
 
 9249   registry_array[m_registry_array_size].m_access= access;
 
 9250   m_registry_array_size++;
 
 9261   DBUG_ASSERT(name != NULL);
 
 9265   for (i= 0; i<m_registry_array_size; i++)
 
 9267     if (my_strcasecmp(system_charset_info, registry_array[i].m_name->str,
 
 9269       return registry_array[
i].m_access;
 
 9281                          const char *schema_name)
 
 9283   if (grant_internal_info)
 
 9304                         const char *schema_name,
 
 9305                         const char *table_name)
 
 9307   DBUG_ASSERT(grant_internal_info);
 
 9311     schema_access= get_cached_schema_access(grant_internal_info, schema_name);
 
 9328 #ifdef EMBEDDED_LIBRARY 
 9330 #ifdef NO_EMBEDDED_ACCESS_CHECKS 
 9331 #define initialized 0 
 9334 #ifndef HAVE_OPENSSL 
 9335 #define ssl_acceptor_fd 0 
 9336 #define sslaccept(A,B,C) 1 
 9345   bool init_client_charset(uint cs_number)
 
 9347     if (thd_init_client_charset(thd, cs_number))
 
 9349     thd->update_charset();
 
 9350     return thd->is_error();
 
 9353   const CHARSET_INFO *charset() { 
return thd->charset(); }
 
 9379   enum { SUCCESS, FAILURE, RESTART } 
status;
 
 9382   ulong client_capabilities;
 
 9386   my_thread_id  thread_id;
 
 9387   uint      *server_status;
 
 9389   ulong max_client_packet_length;
 
 9394   int vio_is_encrypted;
 
 9397 bool auth_plugin_is_built_in(
const char *plugin_name)
 
 9399  return (plugin_name == native_password_plugin_name.str ||
 
 9400 #
if defined(HAVE_OPENSSL)
 
 9401          plugin_name == sha256_password_plugin_name.str ||
 
 9403          plugin_name == old_password_plugin_name.str);
 
 9406 void optimize_plugin_compare_by_pointer(
LEX_STRING *plugin_name)
 
 9408 #if defined(HAVE_OPENSSL) 
 9409   if (my_strcasecmp(system_charset_info, sha256_password_plugin_name.str,
 
 9410                     plugin_name->str) == 0)
 
 9412     plugin_name->str= sha256_password_plugin_name.str;
 
 9413     plugin_name->length= sha256_password_plugin_name.length;
 
 9417   if (my_strcasecmp(system_charset_info, native_password_plugin_name.str,
 
 9418                     plugin_name->str) == 0)
 
 9420     plugin_name->str= native_password_plugin_name.str;
 
 9421     plugin_name->length= native_password_plugin_name.length;
 
 9424   if (my_strcasecmp(system_charset_info, old_password_plugin_name.str,
 
 9425                     plugin_name->str) == 0)
 
 9427     plugin_name->str= old_password_plugin_name.str;
 
 9428     plugin_name->length= old_password_plugin_name.length;
 
 9435 void init_default_auth_plugin()
 
 9437   default_auth_plugin_name.str= native_password_plugin_name.str;
 
 9438   default_auth_plugin_name.length= native_password_plugin_name.length;
 
 9453 int set_default_auth_plugin(
char *plugin_name, 
int plugin_name_length)
 
 9455   default_auth_plugin_name.str= plugin_name;
 
 9456   default_auth_plugin_name.length= plugin_name_length;
 
 9458   optimize_plugin_compare_by_pointer(&default_auth_plugin_name);
 
 9460 #if defined(HAVE_OPENSSL) 
 9461   if (default_auth_plugin_name.str == sha256_password_plugin_name.str)
 
 9467     global_system_variables.old_passwords= 2;
 
 9471   if (default_auth_plugin_name.str != native_password_plugin_name.str)
 
 9480 static void login_failed_error(
MPVIO_EXT *mpvio, 
int passwd_used)
 
 9482   THD *thd= current_thd;
 
 9483   if (passwd_used == 2)
 
 9485     my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0),
 
 9488     general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_NO_PASSWORD_ERROR),
 
 9496     if (log_warnings > 1)
 
 9498       sql_print_warning(ER(ER_ACCESS_DENIED_NO_PASSWORD_ERROR),
 
 9505     my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
 
 9508              passwd_used ? ER(ER_YES) : ER(ER_NO));
 
 9509     general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
 
 9512                       passwd_used ? ER(ER_YES) : ER(ER_NO));
 
 9518     if (log_warnings > 1)
 
 9520       sql_print_warning(ER(ER_ACCESS_DENIED_ERROR),
 
 9523                         passwd_used ? ER(ER_YES) : ER(ER_NO));      
 
 9553 static bool send_server_handshake_packet(
MPVIO_EXT *mpvio,
 
 9554                                          const char *data, uint data_len)
 
 9556   DBUG_ASSERT(mpvio->
status == MPVIO_EXT::FAILURE);
 
 9557   DBUG_ASSERT(data_len <= 255);
 
 9559   char *buff= (
char *) my_alloca(1 + SERVER_VERSION_LENGTH + data_len + 64);
 
 9560   char scramble_buf[SCRAMBLE_LENGTH];
 
 9563   DBUG_ENTER(
"send_server_handshake_packet");
 
 9564   *end++= protocol_version;
 
 9566   mpvio->client_capabilities= CLIENT_BASIC_FLAGS;
 
 9568   if (opt_using_transactions)
 
 9569     mpvio->client_capabilities|= CLIENT_TRANSACTIONS;
 
 9571   mpvio->client_capabilities|= CAN_CLIENT_COMPRESS;
 
 9573   if (ssl_acceptor_fd)
 
 9575     mpvio->client_capabilities|= CLIENT_SSL;
 
 9576     mpvio->client_capabilities|= CLIENT_SSL_VERIFY_SERVER_CERT;
 
 9586   if (data_len < SCRAMBLE_LENGTH)
 
 9594       memcpy(scramble_buf, data, data_len);
 
 9595       memset(scramble_buf + data_len, 0, SCRAMBLE_LENGTH - data_len);
 
 9609       create_random_string(mpvio->scramble, SCRAMBLE_LENGTH, mpvio->rand);
 
 9610       data= mpvio->scramble;
 
 9612     data_len= SCRAMBLE_LENGTH;
 
 9615   end= strnmov(end, server_version, SERVER_VERSION_LENGTH) + 1;
 
 9616   int4store((uchar*) end, mpvio->thread_id);
 
 9624   end= (
char*) memcpy(end, data, SCRAMBLE_LENGTH_323);
 
 9625   end+= SCRAMBLE_LENGTH_323;
 
 9628   int2store(end, mpvio->client_capabilities);
 
 9630   end[2]= (char) default_charset_info->number;
 
 9631   int2store(end + 3, mpvio->server_status[0]);
 
 9632   int2store(end + 5, mpvio->client_capabilities >> 16);
 
 9634   DBUG_EXECUTE_IF(
"poison_srv_handshake_scramble_len", end[7]= -100;);
 
 9635   memset(end + 8, 0, 10);
 
 9638   end= (
char*) memcpy(end, data + SCRAMBLE_LENGTH_323,
 
 9639                       data_len - SCRAMBLE_LENGTH_323);
 
 9640   end+= data_len - SCRAMBLE_LENGTH_323;
 
 9641   end= strmake(end, plugin_name(mpvio->
plugin)->str,
 
 9642                     plugin_name(mpvio->
plugin)->length);
 
 9644   int res= 
my_net_write(mpvio->net, (uchar*) buff, (
size_t) (end - buff + 1)) ||
 
 9650 static bool secure_auth(
MPVIO_EXT *mpvio)
 
 9653   if (!opt_secure_auth)
 
 9661   if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
 
 9663     my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
 
 9666     general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
 
 9672     my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
 
 9673     general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
 
 9699 static bool send_plugin_request_packet(
MPVIO_EXT *mpvio,
 
 9700                                        const uchar *data, uint data_len)
 
 9703   DBUG_ASSERT(mpvio->packets_read == 1);
 
 9704   NET *net= mpvio->net;
 
 9705   static uchar switch_plugin_request_buf[]= { 254 };
 
 9707   DBUG_ENTER(
"send_plugin_request_packet");
 
 9708   mpvio->
status= MPVIO_EXT::FAILURE; 
 
 9710   const char *client_auth_plugin=
 
 9713   DBUG_ASSERT(client_auth_plugin);
 
 9724   bool switch_from_long_to_short_scramble=
 
 9726     client_auth_plugin == old_password_plugin_name.str;
 
 9728   if (switch_from_long_to_short_scramble)
 
 9729     DBUG_RETURN (secure_auth(mpvio) ||
 
 9738   bool switch_from_short_to_long_scramble=
 
 9740     client_auth_plugin == native_password_plugin_name.str;
 
 9742   if (switch_from_short_to_long_scramble)
 
 9744     my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
 
 9745     general_log_print(current_thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
 
 9758   if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH))
 
 9760     DBUG_PRINT(
"info", (
"old client sent a COM_CHANGE_USER"));
 
 9763     mpvio->
status= MPVIO_EXT::RESTART; 
 
 9767   DBUG_PRINT(
"info", (
"requesting client to use the %s plugin", 
 
 9768                       client_auth_plugin));
 
 9770                                 (uchar*) client_auth_plugin,
 
 9771                                 strlen(client_auth_plugin) + 1,
 
 9772                                 (uchar*) data, data_len));
 
 9775 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 9788 static bool find_mpvio_user(
MPVIO_EXT *mpvio)
 
 9790   DBUG_ENTER(
"find_mpvio_user");
 
 9791   DBUG_PRINT(
"info", (
"entry: %s", mpvio->auth_info.
user_name));
 
 9792   DBUG_ASSERT(mpvio->acl_user == 0);
 
 9794   for (uint i=0; i < acl_users.elements; i++)
 
 9797     if ((!acl_user_tmp->user || 
 
 9798          !strcmp(mpvio->auth_info.
user_name, acl_user_tmp->user)) &&
 
 9799         acl_user_tmp->host.compare_hostname(mpvio->host, mpvio->ip))
 
 9801       mpvio->acl_user= acl_user_tmp->copy(mpvio->mem_root);
 
 9807       if (auth_plugin_is_built_in(acl_user_tmp->plugin.str))
 
 9808         mpvio->acl_user_plugin= mpvio->acl_user->plugin;
 
 9810         make_lex_string_root(mpvio->mem_root, 
 
 9811                              &mpvio->acl_user_plugin, 
 
 9812                              acl_user_tmp->plugin.str, 
 
 9813                              acl_user_tmp->plugin.length, 0);
 
 9819   if (!mpvio->acl_user)
 
 9825   if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
 
 9826                     native_password_plugin_name.str) != 0 &&
 
 9827       my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
 
 9828                     old_password_plugin_name.str) != 0 &&
 
 9829       !(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH))
 
 9832     DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
 
 9833                               native_password_plugin_name.str));
 
 9834     DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
 
 9835                               old_password_plugin_name.str));
 
 9836     my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
 
 9837     general_log_print(current_thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
 
 9841   mpvio->auth_info.
auth_string= mpvio->acl_user->auth_string.str;
 
 9843     (
unsigned long) mpvio->acl_user->auth_string.length;
 
 9845           mpvio->acl_user->user : 
"", USERNAME_LENGTH);
 
 9846   DBUG_PRINT(
"info", (
"exit: user=%s, auth_string=%s, authenticated as=%s" 
 9851                       mpvio->acl_user->plugin.str));
 
 9857 read_client_connect_attrs(
char **ptr, 
size_t *max_bytes_available,
 
 9860   size_t length, length_length;
 
 9863   if (*max_bytes_available < 1)
 
 9868   length= net_field_length_ll((uchar **) ptr);
 
 9869   length_length= *ptr - ptr_save;
 
 9870   if (*max_bytes_available < length_length)
 
 9873   *max_bytes_available-= length_length;
 
 9876   if (length > *max_bytes_available)
 
 9883 #ifdef HAVE_PSI_THREAD_INTERFACE 
 9884   if (PSI_THREAD_CALL(set_thread_connect_attrs)(*ptr, length, from_cs) && log_warnings)
 
 9885     sql_print_warning(
"Connection attributes of length %lu were truncated",
 
 9886                       (
unsigned long) length);
 
 9895 static bool parse_com_change_user_packet(
MPVIO_EXT *mpvio, uint packet_length)
 
 9897   NET *net= mpvio->net;
 
 9899   char *user= (
char*) net->read_pos;
 
 9900   char *end= user + packet_length;
 
 9902   char *passwd= strend(user) + 1;
 
 9903   uint user_len= passwd - user - 1;
 
 9905   char db_buff[NAME_LEN + 1];                 
 
 9906   char user_buff[USERNAME_LENGTH + 1];        
 
 9909   DBUG_ENTER (
"parse_com_change_user_packet");
 
 9912     my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
 9926   uint passwd_len= (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION ?
 
 9927                     (uchar) (*passwd++) : strlen(passwd));
 
 9929   db+= passwd_len + 1;
 
 9936     my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
 9940   uint db_len= strlen(db);
 
 9942   char *ptr= db + db_len + 1;
 
 9946     if (mpvio->charset_adapter->init_client_charset(uint2korr(ptr)))
 
 9951     sql_print_warning(
"Client failed to provide its character set. " 
 9952                       "'%s' will be used as client character set.",
 
 9953                       mpvio->charset_adapter->charset()->csname);
 
 9958   db_len= copy_and_convert(db_buff, 
sizeof(db_buff) - 1, system_charset_info,
 
 9959                            db, db_len, mpvio->charset_adapter->charset(),
 
 9963   user_len= copy_and_convert(user_buff, 
sizeof(user_buff) - 1,
 
 9964                                   system_charset_info, user, user_len,
 
 9965                                   mpvio->charset_adapter->charset(),
 
 9967   user_buff[user_len]= 0;
 
 9970   if (!(mpvio->auth_info.
user_name= my_strndup(user_buff, user_len, MYF(MY_WME))))
 
 9974   if (make_lex_string_root(mpvio->mem_root, 
 
 9975                            &mpvio->
db, db_buff, db_len, 0) == 0)
 
 9982             mpvio->auth_info.
user_name, USERNAME_LENGTH);
 
 9984     mpvio->
status= MPVIO_EXT::SUCCESS;
 
 9988 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
 9989   if (find_mpvio_user(mpvio))
 
 9992   char *client_plugin;
 
 9993   if (mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)
 
 9995     client_plugin= ptr + 2;
 
 9996     if (client_plugin >= end)
 
 9998       my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
 
10004     if (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION)
 
10005       client_plugin= native_password_plugin_name.str;
 
10008       client_plugin=  old_password_plugin_name.str;
 
10015       if (mpvio->acl_user->
salt_len == 0)
 
10016         mpvio->acl_user_plugin= old_password_plugin_name;
 
10020   size_t bytes_remaining_in_packet= end - ptr;
 
10022   if ((mpvio->client_capabilities & CLIENT_CONNECT_ATTRS) &&
 
10023       read_client_connect_attrs(&ptr, &bytes_remaining_in_packet,
 
10024                                 mpvio->charset_adapter->charset()))
 
10025     return packet_error;
 
10027   DBUG_PRINT(
"info", (
"client_plugin=%s, restart", client_plugin));
 
10035   mpvio->
status= MPVIO_EXT::RESTART;
 
10041 #ifndef EMBEDDED_LIBRARY 
10043 typedef char * (*get_proto_string_func_t) (
char **, 
size_t *, 
size_t *);
 
10066 char *get_41_protocol_string(
char **buffer,
 
10067                              size_t *max_bytes_available,
 
10068                              size_t *string_length)
 
10070   char *str= (
char *)memchr(*buffer, 
'\0', *max_bytes_available);
 
10075   *string_length= (size_t)(str - *buffer);
 
10076   *max_bytes_available-= *string_length + 1;
 
10078   *buffer += *string_length + 1;
 
10102 char *get_40_protocol_string(
char **buffer,
 
10103                              size_t *max_bytes_available,
 
10104                              size_t *string_length)
 
10110   if ((*max_bytes_available) == 0)
 
10113     return empty_c_string;
 
10116   str= (
char *) memchr(*buffer, 
'\0', *max_bytes_available);
 
10125     len= *string_length= *max_bytes_available;
 
10127     len= (*string_length= (size_t)(str - *buffer)) + 1;
 
10131   *max_bytes_available-= len;
 
10151 char *get_56_lenc_string(
char **buffer,
 
10152                          size_t *max_bytes_available,
 
10153                          size_t *string_length)
 
10155   static char empty_string[1]= { 
'\0' };
 
10156   char *begin= *buffer;
 
10158   if (*max_bytes_available == 0)
 
10168     --*max_bytes_available;
 
10174     return empty_string;
 
10177   *string_length= (size_t)net_field_length_ll((uchar **)buffer);
 
10179   size_t len_len= (size_t)(*buffer - begin);
 
10181   if (*string_length + len_len > *max_bytes_available)
 
10184   *max_bytes_available -= *string_length + len_len;
 
10185   *buffer += *string_length;
 
10186   return (
char *)(begin + len_len);
 
10207 char *get_41_lenc_string(
char **buffer,
 
10208                          size_t *max_bytes_available,
 
10209                          size_t *string_length)
 
10211  if (*max_bytes_available == 0)
 
10215   size_t str_len= (size_t)(
unsigned char)**buffer;
 
10232   if (str_len >= *max_bytes_available)
 
10235   char *str= *buffer+1;
 
10236   *string_length= str_len;
 
10237   *max_bytes_available-= *string_length + 1;
 
10238   *buffer+= *string_length + 1;
 
10241 #endif // EMBEDDED LIBRARY 
10245 static ulong parse_client_handshake_packet(
MPVIO_EXT *mpvio,
 
10246                                            uchar **buff, ulong pkt_len)
 
10248 #ifndef EMBEDDED_LIBRARY 
10249   NET *net= mpvio->net;
 
10251   bool packet_has_required_size= 
false;
 
10252   DBUG_ASSERT(mpvio->
status == MPVIO_EXT::FAILURE);
 
10254   uint charset_code= 0;
 
10255   end= (
char *)net->read_pos;
 
10261   size_t bytes_remaining_in_packet= pkt_len;
 
10267   if (bytes_remaining_in_packet < 2)
 
10268     return packet_error;
 
10270   mpvio->client_capabilities= uint2korr(end);
 
10276   if (bytes_remaining_in_packet == 4 &&
 
10277       mpvio->client_capabilities & CLIENT_SSL)
 
10279     mpvio->client_capabilities= uint4korr(end);
 
10280     mpvio->max_client_packet_length= 0xfffff;
 
10281     charset_code= global_system_variables.character_set_client->number;
 
10282     sql_print_warning(
"Client failed to provide its character set. " 
10283                       "'%s' will be used as client character set.",
 
10284                       global_system_variables.character_set_client->csname);
 
10285     if (mpvio->charset_adapter->init_client_charset(charset_code))
 
10286       return packet_error;
 
10290   if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
 
10291     packet_has_required_size= bytes_remaining_in_packet >= 
 
10292       AUTH_PACKET_HEADER_SIZE_PROTO_41;
 
10294     packet_has_required_size= bytes_remaining_in_packet >=
 
10295       AUTH_PACKET_HEADER_SIZE_PROTO_40;
 
10297   if (!packet_has_required_size)
 
10298     return packet_error;
 
10300   if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
 
10302     mpvio->client_capabilities= uint4korr(end);
 
10303     mpvio->max_client_packet_length= uint4korr(end + 4);
 
10304     charset_code= (uint)(uchar)*(end + 8);
 
10308     end+= AUTH_PACKET_HEADER_SIZE_PROTO_41;
 
10309     bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_PROTO_41;
 
10313     mpvio->client_capabilities= uint2korr(end);
 
10314     mpvio->max_client_packet_length= uint3korr(end + 2);
 
10315     end+= AUTH_PACKET_HEADER_SIZE_PROTO_40;
 
10316     bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_PROTO_40;
 
10321     charset_code= global_system_variables.character_set_client->number;
 
10322     sql_print_warning(
"Client failed to provide its character set. " 
10323                       "'%s' will be used as client character set.",
 
10324                       global_system_variables.character_set_client->csname);
 
10327   DBUG_PRINT(
"info", (
"client_character_set: %u", charset_code));
 
10328   if (mpvio->charset_adapter->init_client_charset(charset_code))
 
10329     return packet_error;
 
10332 #if defined(HAVE_OPENSSL) 
10333   DBUG_PRINT(
"info", (
"client capabilities: %lu", mpvio->client_capabilities));
 
10340   if (mpvio->client_capabilities & CLIENT_SSL)
 
10342     unsigned long errptr;
 
10345     if (!ssl_acceptor_fd)
 
10346       return packet_error;
 
10348     DBUG_PRINT(
"info", (
"IO layer change in progress..."));
 
10349     if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, &errptr))
 
10351       DBUG_PRINT(
"error", (
"Failed to accept new SSL connection"));
 
10352       return packet_error;
 
10355     DBUG_PRINT(
"info", (
"Reading user information over SSL layer"));
 
10358       DBUG_PRINT(
"error", (
"Failed to read user information (pkt_len= %lu)",
 
10360       return packet_error;
 
10363     mpvio->vio_is_encrypted= 1;
 
10369     bytes_remaining_in_packet= pkt_len;
 
10376     if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
 
10378       packet_has_required_size= bytes_remaining_in_packet >= 
 
10379         AUTH_PACKET_HEADER_SIZE_PROTO_41;
 
10380       end= (
char *)net->read_pos + AUTH_PACKET_HEADER_SIZE_PROTO_41;
 
10381       bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_41;
 
10385       packet_has_required_size= bytes_remaining_in_packet >= 
 
10386         AUTH_PACKET_HEADER_SIZE_PROTO_40;
 
10387       end= (
char *)net->read_pos + AUTH_PACKET_HEADER_SIZE_PROTO_40;
 
10388       bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_40;
 
10391     if (!packet_has_required_size)
 
10392       return packet_error;
 
10396   if ((mpvio->client_capabilities & CLIENT_TRANSACTIONS) &&
 
10397       opt_using_transactions)
 
10398     net->return_status= mpvio->server_status;
 
10406   get_proto_string_func_t get_string;
 
10408   if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
 
10409     get_string= get_41_protocol_string;
 
10411     get_string= get_40_protocol_string;
 
10421   get_proto_string_func_t get_length_encoded_string;
 
10423   if (mpvio->client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA)
 
10424     get_length_encoded_string= get_56_lenc_string;
 
10426     get_length_encoded_string= get_41_lenc_string;
 
10433   if ((mpvio->client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) &&
 
10434       !(mpvio->client_capabilities & CLIENT_SECURE_CONNECTION))
 
10435     return packet_error;
 
10442   bytes_remaining_in_packet= pkt_len - (end - (
char *)net->read_pos);
 
10445   char *user= get_string(&end, &bytes_remaining_in_packet, &user_len);
 
10447     return packet_error;
 
10454   size_t passwd_len= 0;
 
10455   char *passwd= NULL;
 
10457   if (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION)
 
10462     passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet,
 
10470     passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len);
 
10473   if (passwd == NULL)
 
10474     return packet_error;
 
10479   if (mpvio->client_capabilities & CLIENT_CONNECT_WITH_DB)
 
10481     db= get_string(&end, &bytes_remaining_in_packet, &db_len);
 
10483       return packet_error;
 
10494   size_t client_plugin_len= 0;
 
10495   char *client_plugin= get_string(&end, &bytes_remaining_in_packet,
 
10496                                   &client_plugin_len);
 
10497   if (client_plugin == NULL)
 
10498     client_plugin= &empty_c_string[0];
 
10500   if ((mpvio->client_capabilities & CLIENT_CONNECT_ATTRS) &&
 
10501       read_client_connect_attrs(&end, &bytes_remaining_in_packet,
 
10502                                 mpvio->charset_adapter->charset()))
 
10503     return packet_error;
 
10505   char db_buff[NAME_LEN + 1];           
 
10506   char user_buff[USERNAME_LENGTH + 1];  
 
10518     db_len= copy_and_convert(db_buff, 
sizeof(db_buff) - 1, system_charset_info,
 
10519                              db, db_len, mpvio->charset_adapter->charset(),
 
10521     db_buff[db_len]= 
'\0';
 
10525   user_len= copy_and_convert(user_buff, 
sizeof(user_buff) - 1,
 
10526                              system_charset_info, user, user_len,
 
10527                              mpvio->charset_adapter->charset(),
 
10529   user_buff[user_len]= 
'\0';
 
10533   if (user_len > 1 && user[0] == 
'\'' && user[user_len - 1] == 
'\'')
 
10535     user[user_len - 1]= 0;
 
10540   if (make_lex_string_root(mpvio->mem_root, 
 
10541                            &mpvio->
db, db, db_len, 0) == 0)
 
10542     return packet_error; 
 
10545   if (!(mpvio->auth_info.
user_name= my_strndup(user, user_len, MYF(MY_WME))))
 
10546     return packet_error; 
 
10552     mpvio->
status= MPVIO_EXT::SUCCESS;
 
10553     return packet_error;
 
10556   if (find_mpvio_user(mpvio))
 
10557     return packet_error;
 
10559   if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH))
 
10564     if (mpvio->client_capabilities & CLIENT_SECURE_CONNECTION)
 
10565       client_plugin= native_password_plugin_name.str;
 
10571       client_plugin= old_password_plugin_name.str;
 
10578       if (mpvio->acl_user->
salt_len == 0)
 
10579         mpvio->acl_user_plugin= old_password_plugin_name;
 
10592   if (my_strcasecmp(system_charset_info, mpvio->acl_user_plugin.str,
 
10593                     plugin_name(mpvio->
plugin)->str) != 0)
 
10598     mpvio->
status= MPVIO_EXT::RESTART;
 
10599     return packet_error;
 
10608   const char *client_auth_plugin=
 
10611   if (client_auth_plugin &&
 
10612       my_strcasecmp(system_charset_info, client_plugin, client_auth_plugin))
 
10615     if (send_plugin_request_packet(mpvio,
 
10618       return packet_error;
 
10621     passwd = (
char*) mpvio->net->read_pos;
 
10624   *buff= (uchar*) passwd;
 
10642 wrap_plguin_data_into_proper_command(
NET *net, 
 
10643                                      const uchar *packet, 
int packet_len)
 
10660                                    const uchar *packet, 
int packet_len)
 
10665   DBUG_ENTER(
"server_mpvio_write_packet");
 
10670   if (!((!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH)) && 
 
10671         mpvio->
status == MPVIO_EXT::RESTART &&
 
10678     res= send_server_handshake_packet(mpvio, (
char*) packet, packet_len);
 
10679   else if (mpvio->
status == MPVIO_EXT::RESTART)
 
10680     res= send_plugin_request_packet(mpvio, packet, packet_len);
 
10682     res= wrap_plguin_data_into_proper_command(mpvio->net, packet, packet_len);
 
10702   DBUG_ENTER(
"server_mpvio_read_packet");
 
10710       pkt_len= packet_error;
 
10716     DBUG_ASSERT(mpvio->
status == MPVIO_EXT::RESTART);
 
10717     DBUG_ASSERT(mpvio->packets_read > 0);
 
10724     const char *client_auth_plugin=
 
10726     if (client_auth_plugin == 0 ||
 
10728                       client_auth_plugin) == 0)
 
10730       mpvio->
status= MPVIO_EXT::FAILURE;
 
10733       mpvio->packets_read++;
 
10738     if (!(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH))
 
10740       mpvio->
status= MPVIO_EXT::FAILURE;
 
10741       pkt_len= packet_error;
 
10751       pkt_len= packet_error;
 
10758   if (pkt_len == packet_error)
 
10761   mpvio->packets_read++;
 
10767   if (mpvio->packets_read == 1)
 
10769     pkt_len= parse_client_handshake_packet(mpvio, buf, pkt_len);
 
10770     if (pkt_len == packet_error)
 
10774     *buf= mpvio->net->read_pos;
 
10776   DBUG_RETURN((
int)pkt_len);
 
10779   if (mpvio->
status == MPVIO_EXT::FAILURE)
 
10781     my_error(ER_HANDSHAKE_ERROR, MYF(0));
 
10794   mpvio_info(mpvio->net->vio, info);
 
10797 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
10798 static bool acl_check_ssl(THD *thd, 
const ACL_USER *acl_user)
 
10800 #if defined(HAVE_OPENSSL) 
10801   Vio *vio= thd->net.vio;
 
10802   SSL *ssl= (SSL *) vio->ssl_arg;
 
10812   switch (acl_user->ssl_type) {
 
10813   case SSL_TYPE_NOT_SPECIFIED:                  
 
10814   case SSL_TYPE_NONE:                           
 
10816 #if defined(HAVE_OPENSSL) 
10818     return vio_type(vio) != VIO_TYPE_SSL;
 
10819   case SSL_TYPE_X509: 
 
10827     if (vio_type(vio) == VIO_TYPE_SSL &&
 
10828         SSL_get_verify_result(ssl) == X509_V_OK &&
 
10829         (cert= SSL_get_peer_certificate(ssl)))
 
10835   case SSL_TYPE_SPECIFIED: 
 
10837     if (vio_type(vio) != VIO_TYPE_SSL ||
 
10838         SSL_get_verify_result(ssl) != X509_V_OK)
 
10840     if (acl_user->ssl_cipher)
 
10842       DBUG_PRINT(
"info", (
"comparing ciphers: '%s' and '%s'",
 
10843                          acl_user->ssl_cipher, SSL_get_cipher(ssl)));
 
10844       if (strcmp(acl_user->ssl_cipher, SSL_get_cipher(ssl)))
 
10847           sql_print_information(
"X509 ciphers mismatch: should be '%s' but is '%s'",
 
10848                             acl_user->ssl_cipher, SSL_get_cipher(ssl));
 
10853     if (!(cert= SSL_get_peer_certificate(ssl)))
 
10856     if (acl_user->x509_issuer)
 
10858       char *ptr= X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
 
10859       DBUG_PRINT(
"info", (
"comparing issuers: '%s' and '%s'",
 
10860                          acl_user->x509_issuer, ptr));
 
10861       if (strcmp(acl_user->x509_issuer, ptr))
 
10864           sql_print_information(
"X509 issuer mismatch: should be '%s' " 
10865                             "but is '%s'", acl_user->x509_issuer, ptr);
 
10873     if (acl_user->x509_subject)
 
10875       char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
 
10876       DBUG_PRINT(
"info", (
"comparing subjects: '%s' and '%s'",
 
10877                          acl_user->x509_subject, ptr));
 
10878       if (strcmp(acl_user->x509_subject, ptr))
 
10881           sql_print_information(
"X509 subject mismatch: should be '%s' but is '%s'",
 
10882                           acl_user->x509_subject, ptr);
 
10905 static int do_auth_once(THD *thd, 
LEX_STRING *auth_plugin_name,
 
10908   DBUG_ENTER(
"do_auth_once");
 
10909   int res= 
CR_OK, old_status= MPVIO_EXT::FAILURE;
 
10910   bool unlock_plugin= 
false;
 
10913   if (auth_plugin_name->str == native_password_plugin_name.str)
 
10914     plugin= native_password_plugin;
 
10915 #ifndef EMBEDDED_LIBRARY 
10917   if (auth_plugin_name->str == old_password_plugin_name.str)
 
10918     plugin= old_password_plugin;
 
10921     if (auth_plugin_name->length == 0)
 
10923       auth_plugin_name->str= default_auth_plugin_name.str;
 
10924       auth_plugin_name->length= default_auth_plugin_name.length;
 
10926     if ((plugin= my_plugin_lock_by_name(thd, auth_plugin_name,
 
10927                                         MYSQL_AUTHENTICATION_PLUGIN)))
 
10928       unlock_plugin= 
true;
 
10934   old_status= mpvio->
status;
 
10942       plugin_unlock(thd, plugin);
 
10949     inc_host_errors(mpvio->ip, &errors);
 
10950     my_error(ER_PLUGIN_IS_NOT_LOADED, MYF(0), auth_plugin_name->str);
 
10962   if (old_status == MPVIO_EXT::RESTART && mpvio->
status == MPVIO_EXT::RESTART)
 
10963     mpvio->
status= MPVIO_EXT::FAILURE; 
 
10970 server_mpvio_initialize(THD *thd, 
MPVIO_EXT *mpvio,
 
10976   mpvio->
info= server_mpvio_info;
 
10977   mpvio->auth_info.
host_or_ip= thd->security_ctx->host_or_ip;
 
10979     (
unsigned int) strlen(thd->security_ctx->host_or_ip);
 
10982 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) 
10983   if (thd->net.vio && thd->net.vio->ssl_arg)
 
10984     mpvio->vio_is_encrypted= 1;
 
10987     mpvio->vio_is_encrypted= 0;
 
10988   mpvio->
status= MPVIO_EXT::FAILURE;
 
10990   mpvio->client_capabilities= thd->client_capabilities;
 
10991   mpvio->mem_root= thd->mem_root;
 
10992   mpvio->scramble= thd->scramble;
 
10993   mpvio->rand= &thd->rand;
 
10994   mpvio->thread_id= thd->thread_id;
 
10995   mpvio->server_status= &thd->server_status;
 
10996   mpvio->net= &thd->net;
 
10997   mpvio->ip= (
char *) thd->security_ctx->get_ip()->ptr();
 
10998   mpvio->host= (
char *) thd->security_ctx->get_host()->ptr();
 
10999   mpvio->charset_adapter= charset_adapter;
 
11004 server_mpvio_update_thd(THD *thd, 
MPVIO_EXT *mpvio)
 
11006   thd->client_capabilities= mpvio->client_capabilities;
 
11007   thd->max_client_packet_length= mpvio->max_client_packet_length;
 
11008   if (mpvio->client_capabilities & CLIENT_INTERACTIVE)
 
11009     thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
 
11010   thd->security_ctx->user= mpvio->auth_info.
user_name;
 
11011   if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
 
11012     thd->variables.sql_mode|= MODE_IGNORE_SPACE;
 
11028 acl_authenticate(THD *thd, uint com_change_user_pkt_len)
 
11034   LEX_STRING auth_plugin_name= default_auth_plugin_name;
 
11035   enum  enum_server_command command= com_change_user_pkt_len ? COM_CHANGE_USER
 
11038   DBUG_ENTER(
"acl_authenticate");
 
11041   server_mpvio_initialize(thd, &mpvio, &charset_adapter);
 
11043   DBUG_PRINT(
"info", (
"com_change_user_pkt_len=%u", com_change_user_pkt_len));
 
11050   thd->reset_db(NULL, 0);
 
11052   if (command == COM_CHANGE_USER)
 
11055     mpvio.packets_read++;    
 
11058     thd->set_user_connect(NULL);
 
11060     if (parse_com_change_user_packet(&mpvio, com_change_user_pkt_len))
 
11062       server_mpvio_update_thd(thd, &mpvio);
 
11066     DBUG_ASSERT(mpvio.
status == MPVIO_EXT::RESTART ||
 
11067                 mpvio.
status == MPVIO_EXT::SUCCESS);
 
11072     mpvio.scramble[SCRAMBLE_LENGTH]= 1;
 
11081     res= do_auth_once(thd, &auth_plugin_name, &mpvio);  
 
11088   if (mpvio.
status == MPVIO_EXT::RESTART)
 
11090     DBUG_ASSERT(mpvio.acl_user);
 
11091     DBUG_ASSERT(command == COM_CHANGE_USER ||
 
11092                 my_strcasecmp(system_charset_info, auth_plugin_name.str,
 
11093                               mpvio.acl_user->plugin.str));
 
11094     auth_plugin_name= mpvio.acl_user->plugin;
 
11095     res= do_auth_once(thd, &auth_plugin_name, &mpvio);
 
11098       if (auth_plugin_name.str == native_password_plugin_name.str)
 
11099         thd->variables.old_passwords= 0;
 
11100       if (auth_plugin_name.str == old_password_plugin_name.str)
 
11101         thd->variables.old_passwords= 1;
 
11102       if (auth_plugin_name.str == sha256_password_plugin_name.str)
 
11103         thd->variables.old_passwords= 2;
 
11107   server_mpvio_update_thd(thd, &mpvio);
 
11109   Security_context *sctx= thd->security_ctx;
 
11110   const ACL_USER *acl_user= mpvio.acl_user;
 
11124       general_log_print(thd, command, 
"%s@%s as %s on %s",
 
11128                         mpvio.
db.str ? mpvio.
db.str : (
char*) 
"");
 
11131       general_log_print(thd, command, (
char*) 
"%s@%s on %s",
 
11133                         mpvio.
db.str ? mpvio.
db.str : (
char*) 
"");
 
11136   if (res > 
CR_OK && mpvio.
status != MPVIO_EXT::SUCCESS)
 
11139     DBUG_ASSERT(mpvio.
status == MPVIO_EXT::FAILURE);
 
11157     inc_host_errors(mpvio.ip, &errors);
 
11158     if (!thd->is_error())
 
11163   sctx->proxy_user[0]= 0;
 
11167 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
11168     bool is_proxy_user= FALSE;
 
11169     const char *auth_user = acl_user->user ? acl_user->user : 
"";
 
11172     proxy_user= acl_find_proxy_user(auth_user, sctx->get_host()->ptr(),
 
11173                                     sctx->get_ip()->ptr(),
 
11185         inc_host_errors(mpvio.ip, &errors);
 
11186         if (!thd->is_error())
 
11191       my_snprintf(sctx->proxy_user, 
sizeof(sctx->proxy_user) - 1,
 
11192                   "'%s'@'%s'", auth_user,
 
11193                   acl_user->host.get_host() ? acl_user->host.get_host() : 
"");
 
11197       acl_proxy_user= find_acl_user(proxy_user->get_proxied_host() ? 
 
11198                                     proxy_user->get_proxied_host() : 
"",
 
11200       if (!acl_proxy_user)
 
11204         inc_host_errors(mpvio.ip, &errors);
 
11205         if (!thd->is_error())
 
11210       acl_user= acl_proxy_user->copy(thd->mem_root);
 
11211       DBUG_PRINT(
"info", (
"User %s is a PROXY and will assume a PROXIED" 
11212                           " identity %s", auth_user, acl_user->user));
 
11217     sctx->master_access= acl_user->access;
 
11218     if (acl_user->user)
 
11219       strmake(sctx->priv_user, acl_user->user, USERNAME_LENGTH - 1);
 
11221       *sctx->priv_user= 0;
 
11223     if (acl_user->host.get_host())
 
11224       strmake(sctx->priv_host, acl_user->host.get_host(), MAX_HOSTNAME - 1);
 
11226       *sctx->priv_host= 0;
 
11228 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
11234     if (acl_check_ssl(thd, acl_user))
 
11238       inc_host_errors(mpvio.ip, &errors);
 
11239       if (!thd->is_error())
 
11240         login_failed_error(&mpvio, thd->password);
 
11244     if (unlikely(acl_user && acl_user->password_expired
 
11245         && !(mpvio.client_capabilities & CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)
 
11246         && disconnect_on_expired_password))
 
11254       my_error(ER_MUST_CHANGE_PASSWORD_LOGIN, MYF(0));
 
11255       general_log_print(thd, COM_CONNECT, ER(ER_MUST_CHANGE_PASSWORD_LOGIN));
 
11256       if (log_warnings > 1)
 
11257         sql_print_warning(
"%s", ER(ER_MUST_CHANGE_PASSWORD_LOGIN));
 
11260       inc_host_errors(mpvio.ip, &errors);
 
11265     if ((acl_user->user_resource.questions || acl_user->user_resource.updates ||
 
11266          acl_user->user_resource.conn_per_hour ||
 
11267          acl_user->user_resource.user_conn || 
 
11268          global_system_variables.max_user_connections) &&
 
11269         get_or_create_user_conn(thd,
 
11270           (opt_old_style_user_limits ? sctx->user : sctx->priv_user),
 
11271           (opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host),
 
11272           &acl_user->user_resource))
 
11275     sctx->password_expired= acl_user->password_expired;
 
11279     sctx->skip_grants();
 
11282   if ((uc= thd->get_user_connect()) &&
 
11283       (uc->user_resources.conn_per_hour || uc->user_resources.user_conn ||
 
11284        global_system_variables.max_user_connections) &&
 
11285        check_for_max_user_connections(thd, uc))
 
11291              (
"Capabilities: %lu  packet_length: %ld  Host: '%s'  " 
11292               "Login user: '%s' Priv_user: '%s'  Using password: %s " 
11293               "Access: %lu  db: '%s'",
 
11294               thd->client_capabilities, thd->max_client_packet_length,
 
11295               sctx->host_or_ip, sctx->user, sctx->priv_user,
 
11296               thd->password ? 
"yes": 
"no",
 
11297               sctx->master_access, mpvio.
db.str));
 
11299   if (command == COM_CONNECT &&
 
11300       !(thd->main_security_ctx.master_access & SUPER_ACL))
 
11303     bool count_ok= (connection_count <= max_connections);
 
11307       release_user_connection(thd);
 
11308       statistic_increment(connection_errors_max_connection, &LOCK_status);
 
11309       my_error(ER_CON_COUNT_ERROR, MYF(0));
 
11322   if (mpvio.
db.length)
 
11324     if (mysql_change_db(thd, &mpvio.
db, FALSE))
 
11327       release_user_connection(thd);
 
11330       inc_host_errors(mpvio.ip, &errors);
 
11336     sctx->set_external_user(my_strdup(mpvio.auth_info.
external_user, MYF(0)));
 
11340     thd->get_stmt_da()->disable_status();
 
11344 #ifdef HAVE_PSI_THREAD_INTERFACE 
11345   PSI_THREAD_CALL(set_thread_user_host)
 
11346     (thd->main_security_ctx.user, strlen(thd->main_security_ctx.user),
 
11347     thd->main_security_ctx.host_or_ip, strlen(thd->main_security_ctx.host_or_ip));
 
11369   DBUG_ENTER(
"native_password_authenticate");
 
11372   if (mpvio->scramble[SCRAMBLE_LENGTH])
 
11373     create_random_string(mpvio->scramble, SCRAMBLE_LENGTH, mpvio->rand);
 
11376   if (mpvio->
write_packet(mpvio, (uchar*) mpvio->scramble, SCRAMBLE_LENGTH + 1))
 
11417   if ((pkt_len= mpvio->
read_packet(mpvio, &pkt)) < 0)
 
11419   DBUG_PRINT(
"info", (
"reply read : pkt_len=%d", pkt_len));
 
11421 #ifdef NO_EMBEDDED_ACCESS_CHECKS 
11422   DBUG_RETURN(
CR_OK);
 
11425   DBUG_EXECUTE_IF(
"native_password_bad_reply",
 
11435   if (pkt_len == SCRAMBLE_LENGTH)
 
11440     DBUG_RETURN(check_scramble(pkt, mpvio->scramble, mpvio->acl_user->
salt) ?
 
11444   my_error(ER_HANDSHAKE_ERROR, MYF(0));
 
11456   if (mpvio->scramble[SCRAMBLE_LENGTH])
 
11457     create_random_string(mpvio->scramble, SCRAMBLE_LENGTH, mpvio->rand);
 
11460   if (mpvio->
write_packet(mpvio, (uchar*) mpvio->scramble, SCRAMBLE_LENGTH + 1))
 
11464   if ((pkt_len= mpvio->
read_packet(mpvio, &pkt)) < 0)
 
11467 #ifdef NO_EMBEDDED_ACCESS_CHECKS 
11476   if (pkt_len == SCRAMBLE_LENGTH_323 + 1)
 
11477     pkt_len= strnlen((
char*)pkt, pkt_len);
 
11482   if (secure_auth(mpvio))
 
11487   if (pkt_len == SCRAMBLE_LENGTH_323)
 
11492     return check_scramble_323(pkt, mpvio->scramble,
 
11493                              (ulong *) mpvio->acl_user->
salt) ?
 
11497   my_error(ER_HANDSHAKE_ERROR, MYF(0));
 
11510   return (mpvio->vio_is_encrypted);
 
11513 #if defined(HAVE_OPENSSL) 
11514 #define MAX_CIPHER_LENGTH 1024 
11515 #if !defined(HAVE_YASSL) 
11516 #define AUTH_DEFAULT_RSA_PRIVATE_KEY "private_key.pem" 
11517 #define AUTH_DEFAULT_RSA_PUBLIC_KEY "public_key.pem" 
11519 char *auth_rsa_private_key_path;
 
11520 char *auth_rsa_public_key_path;
 
11522 class Rsa_authentication_keys
 
11526   RSA *m_private_key;
 
11528   char *m_pem_public_key;
 
11538   void get_key_file_path(
char *key, 
String *key_file_path)
 
11544     if (strchr(key, FN_LIBCHAR) != NULL ||
 
11545         strchr(key, FN_LIBCHAR2) != NULL)
 
11546       key_file_path->set_quick(key, strlen(key), system_charset_info);
 
11549       key_file_path->append(mysql_real_data_home, strlen(mysql_real_data_home));
 
11550       if ((*key_file_path)[key_file_path->length()] != FN_LIBCHAR)
 
11551         key_file_path->append(FN_LIBCHAR);
 
11552       key_file_path->append(key);
 
11571   bool read_key_file(RSA **key_ptr, 
bool is_priv_key, 
char **key_text_buffer)
 
11575     const char *key_type;
 
11576     FILE *key_file= NULL;
 
11578     key= is_priv_key ? auth_rsa_private_key_path : auth_rsa_public_key_path;
 
11579     key_type= is_priv_key ? 
"private" : 
"public";
 
11582     get_key_file_path(key, &key_file_path);
 
11587     if ((key_file= fopen(key_file_path.c_ptr(), 
"r")) == NULL)
 
11589       sql_print_information(
"RSA %s key file not found: %s." 
11590                             " Some authentication plugins will not work.",
 
11591                             key_type, key_file_path.c_ptr());
 
11595         *key_ptr= is_priv_key ? PEM_read_RSAPrivateKey(key_file, 0, 0, 0) :
 
11596                                 PEM_read_RSA_PUBKEY(key_file, 0, 0, 0);
 
11600         char error_buf[MYSQL_ERRMSG_SIZE];
 
11601         ERR_error_string_n(ERR_get_error(), error_buf, MYSQL_ERRMSG_SIZE);
 
11602         sql_print_error(
"Failure to parse RSA %s key (file exists): %s:" 
11603                         " %s", key_type, key_file_path.c_ptr(), error_buf);
 
11618         fseek(key_file, 0, SEEK_END);
 
11619         filesize= ftell(key_file);
 
11620         fseek(key_file, 0, SEEK_SET);
 
11621         *key_text_buffer= 
new char[filesize+1];
 
11622         (void) fread(*key_text_buffer, filesize, 1, key_file);
 
11623         (*key_text_buffer)[filesize]= 
'\0';
 
11631   Rsa_authentication_keys()
 
11636     m_pem_public_key= 0;
 
11639   ~Rsa_authentication_keys()
 
11646       RSA_free(m_private_key);
 
11650       RSA_free(m_public_key);
 
11654     if (m_pem_public_key)
 
11655       delete [] m_pem_public_key;
 
11658   void *allocate_pem_buffer(
size_t buffer_len)
 
11660     m_pem_public_key= 
new char[buffer_len];
 
11661     return m_pem_public_key;
 
11664   RSA *get_private_key()
 
11666     return m_private_key;
 
11669   RSA *get_public_key()
 
11671     return m_public_key;
 
11674   int get_cipher_length()
 
11676     return (m_cipher_len= RSA_size(m_public_key));
 
11688   bool read_rsa_keys()
 
11690     RSA *rsa_private_key_ptr= NULL;
 
11691     RSA *rsa_public_key_ptr= NULL;
 
11692     char *pub_key_buff= NULL; 
 
11694     if ((strlen(auth_rsa_private_key_path) == 0) &&
 
11695         (strlen(auth_rsa_public_key_path) == 0))
 
11697       sql_print_information(
"RSA key files not found." 
11698                             " Some authentication plugins will not work.");
 
11705     if (read_key_file(&rsa_private_key_ptr, 
true, NULL))
 
11711     if (read_key_file(&rsa_public_key_ptr, 
false, &pub_key_buff))
 
11713       if (rsa_private_key_ptr)
 
11714         RSA_free(rsa_private_key_ptr);
 
11727     if (rsa_private_key_ptr && rsa_public_key_ptr)
 
11729       int buff_len= strlen(pub_key_buff);
 
11730       char *pem_file_buffer= (
char *)allocate_pem_buffer(buff_len + 1);
 
11731       strncpy(pem_file_buffer, pub_key_buff, buff_len);
 
11732       pem_file_buffer[buff_len]= 
'\0';
 
11734       m_private_key= rsa_private_key_ptr;
 
11735       m_public_key= rsa_public_key_ptr;
 
11737       delete [] pub_key_buff; 
 
11741       if (rsa_private_key_ptr)
 
11742         RSA_free(rsa_private_key_ptr);
 
11744       if (rsa_public_key_ptr)
 
11746         delete [] pub_key_buff; 
 
11747         RSA_free(rsa_public_key_ptr);
 
11753   const char *get_public_key_as_pem(
void)
 
11755     return m_pem_public_key;
 
11760 static Rsa_authentication_keys g_rsa_keys;
 
11765 int show_rsa_public_key(THD *thd, 
SHOW_VAR *var, 
char *buff)
 
11767   var->type= SHOW_CHAR;
 
11768   var->value= 
const_cast<char *
>(g_rsa_keys.get_public_key_as_pem());
 
11773 void deinit_rsa_keys(
void)
 
11775   g_rsa_keys.free_memory();  
 
11783   FileCloser(FILE *to_be_closed) : m_file(to_be_closed) {}
 
11786     if (m_file != NULL)
 
11801 bool init_rsa_keys(
void)
 
11803   return (g_rsa_keys.read_rsa_keys());
 
11805 #endif // ifndef HAVE_YASSL 
11807 static MYSQL_PLUGIN plugin_info_ptr;
 
11809 int init_sha256_password_handler(MYSQL_PLUGIN 
plugin_ref)
 
11811   plugin_info_ptr= plugin_ref;
 
11836   char  *user_salt_begin;
 
11837   char  *user_salt_end;
 
11838   char scramble[SCRAMBLE_LENGTH + 1];
 
11839   char stage2[CRYPT_MAX_PASSWORD_SIZE + 1];
 
11840   String scramble_response_packet;
 
11841 #if !defined(HAVE_YASSL) 
11842   int cipher_length= 0;
 
11843   unsigned char plain_text[MAX_CIPHER_LENGTH];
 
11844   RSA *private_key= NULL;
 
11845   RSA *public_key= NULL;
 
11848   DBUG_ENTER(
"sha256_password_authenticate");
 
11850   generate_user_salt(scramble, SCRAMBLE_LENGTH + 1);
 
11852   if (vio->
write_packet(vio, (
unsigned char *) scramble, SCRAMBLE_LENGTH))
 
11859   if ((pkt_len= vio->
read_packet(vio, &pkt)) == -1)
 
11866   if (pkt_len == 1 && *pkt == 0)
 
11874       DBUG_RETURN(
CR_OK);
 
11881   if (!my_vio_is_encrypted(vio))
 
11883  #if !defined(HAVE_YASSL) 
11888     private_key= g_rsa_keys.get_private_key();
 
11889     public_key=  g_rsa_keys.get_public_key();
 
11894     if (private_key == NULL || public_key == NULL)
 
11896       my_plugin_log_message(&plugin_info_ptr, MY_ERROR_LEVEL, 
 
11897         "Authentication requires either RSA keys or SSL encryption");
 
11902     if ((cipher_length= g_rsa_keys.get_cipher_length()) > MAX_CIPHER_LENGTH)
 
11904       my_plugin_log_message(&plugin_info_ptr, MY_ERROR_LEVEL, 
 
11905         "RSA key cipher length of %u is too long. Max value is %u.",
 
11906         g_rsa_keys.get_cipher_length(), MAX_CIPHER_LENGTH);
 
11915     if (pkt_len == 1 && *pkt == 1)
 
11917       uint pem_length= strlen(g_rsa_keys.get_public_key_as_pem());
 
11919                             (
unsigned char *)g_rsa_keys.get_public_key_as_pem(),
 
11923       if ((pkt_len= vio->
read_packet(vio, &pkt)) == -1)
 
11931     if (pkt_len != cipher_length)
 
11935     RSA_private_decrypt(cipher_length, pkt, plain_text, private_key,
 
11936                         RSA_PKCS1_OAEP_PADDING);
 
11938     plain_text[cipher_length]= 
'\0'; 
 
11939     xor_string((
char *) plain_text, cipher_length,
 
11940                (
char *) scramble, SCRAMBLE_LENGTH);
 
11946     pkt_len= strlen((
char *) plain_text) + 1; 
 
11964   if (extract_user_salt(&user_salt_begin, &user_salt_end) != CRYPT_SALT_LENGTH)
 
11967     my_plugin_log_message(&plugin_info_ptr, MY_ERROR_LEVEL, 
 
11968       "Password salt for user '%s' is corrupt.",
 
11974   my_crypt_genhash(stage2,
 
11975                      CRYPT_MAX_PASSWORD_SIZE,
 
11978                      (
char *) user_salt_begin,
 
11979                      (
const char **) 0);
 
11987     DBUG_RETURN(
CR_OK);
 
11992 #if !defined(HAVE_YASSL) 
11993 static MYSQL_SYSVAR_STR(private_key_path, auth_rsa_private_key_path,
 
11994         PLUGIN_VAR_READONLY,
 
11995         "A fully qualified path to the private RSA key used for authentication",
 
11996         NULL, NULL, AUTH_DEFAULT_RSA_PRIVATE_KEY);
 
11997 static MYSQL_SYSVAR_STR(public_key_path, auth_rsa_public_key_path,
 
11998         PLUGIN_VAR_READONLY,
 
11999         "A fully qualified path to the public RSA key used for authentication",
 
12000         NULL, NULL, AUTH_DEFAULT_RSA_PUBLIC_KEY);
 
12003   MYSQL_SYSVAR(private_key_path),
 
12004   MYSQL_SYSVAR(public_key_path),
 
12007 #endif // HAVE_YASSL 
12008 #endif // HAVE_OPENSSL 
12012   MYSQL_AUTHENTICATION_INTERFACE_VERSION,
 
12013   native_password_plugin_name.str,
 
12014   native_password_authenticate
 
12019   MYSQL_AUTHENTICATION_INTERFACE_VERSION,
 
12020   old_password_plugin_name.str,
 
12021   old_password_authenticate
 
12024 #if defined(HAVE_OPENSSL) 
12027   MYSQL_AUTHENTICATION_INTERFACE_VERSION,
 
12028   sha256_password_plugin_name.str,
 
12029   sha256_password_authenticate
 
12033 mysql_declare_plugin(mysql_password)
 
12035   MYSQL_AUTHENTICATION_PLUGIN,                  
 
12036   &native_password_handler,                     
 
12037   native_password_plugin_name.str,              
 
12038   "R.J.Silk, Sergei Golubchik",                 
 
12039   "Native MySQL authentication",                
 
12040   PLUGIN_LICENSE_GPL,                           
 
12050   MYSQL_AUTHENTICATION_PLUGIN,                  
 
12051   &old_password_handler,                        
 
12052   old_password_plugin_name.str,                 
 
12053   "R.J.Silk, Sergei Golubchik",                 
 
12054   "Old MySQL-4.0 authentication",               
 
12055   PLUGIN_LICENSE_GPL,                           
 
12064 #if defined(HAVE_OPENSSL) 
12067   MYSQL_AUTHENTICATION_PLUGIN,                  
 
12068   &sha256_password_handler,                     
 
12069   sha256_password_plugin_name.str,              
 
12071   "SHA256 password authentication",             
 
12072   PLUGIN_LICENSE_GPL,                           
 
12073   &init_sha256_password_handler,                
 
12077 #if !defined(HAVE_YASSL) 
12078   sha256_password_sysvars,                      
 
12086 mysql_declare_plugin_end;
 
12094 int check_password_strength(
String *password)
 
12097   DBUG_ASSERT(password != NULL);
 
12098   plugin_ref plugin= my_plugin_lock_by_name(0, &validate_password_plugin_name,
 
12099                                             MYSQL_VALIDATE_PASSWORD_PLUGIN);
 
12105     res= password_strength->get_password_strength(password);
 
12106     plugin_unlock(0, plugin);
 
12112 int check_password_policy(
String *password)
 
12118     password= &empty_string;
 
12120   plugin= my_plugin_lock_by_name(0, &validate_password_plugin_name,
 
12121                                  MYSQL_VALIDATE_PASSWORD_PLUGIN);
 
12127     if (!password_validate->validate_password(password))
 
12129       my_error(ER_NOT_VALID_PASSWORD, MYF(0));
 
12130       plugin_unlock(0, plugin);
 
12133     plugin_unlock(0, plugin);
 
12138 #ifndef NO_EMBEDDED_ACCESS_CHECKS 
12139 my_bool validate_user_plugins= TRUE;
 
12148 validate_user_plugin_records()
 
12150   DBUG_ENTER(
"validate_user_plugin_records");
 
12151   if (!validate_user_plugins)
 
12154   lock_plugin_data();
 
12155   for (uint i=0 ; i < acl_users.elements ; i++)
 
12160     if (acl_user->plugin.length)
 
12163       if (!auth_plugin_is_built_in(acl_user->plugin.str))
 
12165         plugin= plugin_find_by_type(&acl_user->plugin,
 
12166                                     MYSQL_AUTHENTICATION_PLUGIN);
 
12170           sql_print_warning(
"The plugin '%.*s' used to authenticate " 
12171                             "user '%s'@'%.*s' is not loaded." 
12172                             " Nobody can currently login using this account.",
 
12173                             (
int) acl_user->plugin.length, acl_user->plugin.str,
 
12175                             acl_user->host.get_host_len(), 
 
12176                             acl_user->host.get_host());
 
12179       if (acl_user->plugin.str == sha256_password_plugin_name.str &&
 
12180 #
if !defined(HAVE_YASSL)
 
12181           (!g_rsa_keys.get_private_key() || !g_rsa_keys.get_public_key()) &&
 
12185           sql_print_warning(
"The plugin '%s' is used to authenticate " 
12186                             "user '%s'@'%.*s', " 
12187 #
if !defined(HAVE_YASSL)
 
12188                             "but neither SSL nor RSA keys are " 
12193                             "Nobody can currently login using this account.",
 
12194                             sha256_password_plugin_name.str,
 
12196                             acl_user->host.get_host_len(), 
 
12197                             acl_user->host.get_host());
 
12201   unlock_plugin_data();
 
12205 #endif // NO_EMBEDDED_ACCESS_CHECKS