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