4419 Harin Vadodaria 2012-09-06
wl#6486 : Refactoring user management code
(authentication / authorization)
Description : refactoring of sql_authentication
code.
modified:
sql/auth/auth_common.h
sql/auth/sql_acl.cc
sql/auth/sql_acl.h
sql/auth/sql_authentication.cc
sql/auth/sql_authentication.h
sql/sql_class.cc
sql/sql_connect.cc
sql/sql_parse.cc
4418 Harin Vadodaria 2012-09-05
wl#6486 : Refactoring user management code
authentication / authorization)
Description : Moved authentication related
code to sql_authentication.h
and sql_authentication.cc
added:
sql/auth/sql_authentication.h
modified:
sql/CMakeLists.txt
sql/auth/auth_common.h
sql/auth/sql_acl.cc
sql/auth/sql_authentication.cc
=== modified file 'sql/auth/auth_common.h'
--- a/sql/auth/auth_common.h 2012-09-05 11:40:51 +0000
+++ b/sql/auth/auth_common.h 2012-09-06 12:02:23 +0000
@@ -6,11 +6,6 @@
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + \
1 + USERNAME_LENGTH + 1)
-/** Size of the header fields of an authentication packet. */
-#define AUTH_PACKET_HEADER_SIZE_PROTO_41 32
-#define AUTH_PACKET_HEADER_SIZE_PROTO_40 5
-
-
/* Classes */
class ACL_HOST_AND_IP
@@ -198,6 +193,9 @@ set_user_salt(ACL_USER *acl_user, const
extern DYNAMIC_ARRAY acl_users, acl_dbs, acl_proxy_users;
extern hash_filo *acl_cache;
extern bool initialized;
+extern bool allow_all_hosts;
+extern HASH acl_check_hosts;
+extern DYNAMIC_ARRAY acl_wild_hosts;
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
=== modified file 'sql/auth/sql_acl.cc'
--- a/sql/auth/sql_acl.cc 2012-09-05 11:40:51 +0000
+++ b/sql/auth/sql_acl.cc 2012-09-06 12:02:23 +0000
@@ -432,9 +432,10 @@ uchar* acl_entry_get_key(acl_entry *entr
DYNAMIC_ARRAY acl_users, acl_dbs, acl_proxy_users;
static MEM_ROOT global_acl_memory, memex;
bool initialized=0;
-static bool allow_all_hosts=1;
-static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash;
-static DYNAMIC_ARRAY acl_wild_hosts;
+bool allow_all_hosts=1;
+HASH acl_check_hosts;
+static HASH column_priv_hash, proc_priv_hash, func_priv_hash;
+DYNAMIC_ARRAY acl_wild_hosts;
hash_filo *acl_cache;
static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0);
@@ -1277,45 +1278,6 @@ void rebuild_check_host(void)
}
-/* Return true if there is no users that can match the given host */
-
-bool acl_check_host(const char *host, const char *ip)
-{
- mysql_mutex_lock(&acl_cache->lock);
- if (allow_all_hosts)
- {
-
- mysql_mutex_unlock(&acl_cache->lock);
- return 0;
- }
-
- if ((host && my_hash_search(&acl_check_hosts,(uchar*) host,strlen(host))) ||
- (ip && my_hash_search(&acl_check_hosts,(uchar*) ip, strlen(ip))))
- {
- mysql_mutex_unlock(&acl_cache->lock);
- return 0; // Found host
- }
- for (uint i=0 ; i < acl_wild_hosts.elements ; i++)
- {
- ACL_HOST_AND_IP *acl=dynamic_element(&acl_wild_hosts,i,ACL_HOST_AND_IP*);
- if (acl->compare_hostname(host, ip))
- {
- mysql_mutex_unlock(&acl_cache->lock);
- return 0; // Host ok
- }
- }
- mysql_mutex_unlock(&acl_cache->lock);
- if (ip != NULL)
- {
- /* Increment HOST_CACHE.COUNT_HOST_ACL_ERRORS. */
- Host_errors errors;
- errors.m_host_acl= 1;
- inc_host_errors(ip, &errors);
- }
- return 1; // Host is not allowed
-}
-
-
/**
Check if the user is allowed to change password
=== modified file 'sql/auth/sql_acl.h'
--- a/sql/auth/sql_acl.h 2012-09-04 07:22:36 +0000
+++ b/sql/auth/sql_acl.h 2012-09-06 12:02:23 +0000
@@ -242,10 +242,8 @@ my_bool acl_reload(THD *thd);
void acl_free(bool end=0);
ulong acl_get(const char *host, const char *ip,
const char *user, const char *db, my_bool db_is_pattern);
-int acl_authenticate(THD *thd, uint com_change_user_pkt_len);
bool acl_getroot(Security_context *sctx, char *user, char *host,
char *ip, char *db);
-bool acl_check_host(const char *host, const char *ip);
int check_change_password(THD *thd, const char *host, const char *user,
char *password, uint password_len);
bool change_password(THD *thd, const char *host, const char *user,
=== modified file 'sql/auth/sql_authentication.cc'
--- a/sql/auth/sql_authentication.cc 2012-09-05 11:40:51 +0000
+++ b/sql/auth/sql_authentication.cc 2012-09-06 12:02:23 +0000
@@ -42,14 +42,77 @@ LEX_STRING default_auth_plugin_name;
#undef HAVE_OPENSSL
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define initialized 0
-#endif
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
#endif
#ifndef HAVE_OPENSSL
#define ssl_acceptor_fd 0
#define sslaccept(A,B,C) 1
#endif
+/* Declarations */
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+static ACL_PROXY_USER *
+acl_find_proxy_user(const char *user, const char *host, const char *ip,
+ const char *authenticated_as, bool *proxy_used);
+static bool find_mpvio_user(MPVIO_EXT *mpvio);
+static bool read_client_connect_attrs(char **ptr, size_t *max_bytes_available,
+ const CHARSET_INFO *from_cs);
+static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user);
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
+
+#ifndef EMBEDDED_LIBRARY
+static char *get_41_protocol_string(char **buffer,
+ size_t *max_bytes_available,
+ size_t *string_length);
+static char *get_40_protocol_string(char **buffer,
+ size_t *max_bytes_available,
+ size_t *string_length);
+static char *get_56_lenc_string(char **buffer,
+ size_t *max_bytes_available,
+ size_t *string_length);
+static char *get_41_lenc_string(char **buffer,
+ size_t *max_bytes_available,
+ size_t *string_length);
+#endif /* EMBEDDED_LIBRARY */
+
+#if defined(HAVE_OPENSSL)
+static int sha256_password_authenticate(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_SERVER_AUTH_INFO *info);
+#endif /* HAVE_OPENSSL */
+
+static void login_failed_error(MPVIO_EXT *mpvio, int passwd_used);
+static void login_failed_error(MPVIO_EXT *mpvio, int passwd_used);
+static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
+ const char *data, uint data_len);
+static bool secure_auth(MPVIO_EXT *mpvio);
+static bool send_plugin_request_packet(MPVIO_EXT *mpvio,
+ const uchar *data, uint data_len);
+static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length);
+static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
+ uchar **buff, ulong pkt_len);
+static inline int wrap_plguin_data_into_proper_command(NET *net,
+ const uchar *packet,
+ int packet_len);
+static int server_mpvio_write_packet(MYSQL_PLUGIN_VIO *param,
+ const uchar *packet, int packet_len);
+static int server_mpvio_read_packet(MYSQL_PLUGIN_VIO *param, uchar **buf);
+static void server_mpvio_info(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_PLUGIN_VIO_INFO *info);
+static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name,
+ MPVIO_EXT *mpvio);
+static void server_mpvio_initialize(THD *thd, MPVIO_EXT *mpvio,
+ Thd_charset_adapter *charset_adapter);
+static void server_mpvio_update_thd(THD *thd, MPVIO_EXT *mpvio);
+static int native_password_authenticate(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_SERVER_AUTH_INFO *info);
+static int old_password_authenticate(MYSQL_PLUGIN_VIO *vio,
+ MYSQL_SERVER_AUTH_INFO *info);
+
+
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
+
+
/**
Validate if a user can proxy as another user
@@ -89,8 +152,282 @@ acl_find_proxy_user(const char *user, co
DBUG_RETURN(NULL);
}
+
+
+/**
+ Finds acl entry in user database for authentication purposes.
+
+ Finds a user and copies it into mpvio. Reports an authentication
+ failure if a user is not found.
+
+ @note find_acl_user is not the same, because it doesn't take into
+ account the case when user is not empty, but acl_user->user is empty
+
+ @retval 0 found
+ @retval 1 not found
+*/
+static bool find_mpvio_user(MPVIO_EXT *mpvio)
+{
+ DBUG_ENTER("find_mpvio_user");
+ DBUG_PRINT("info", ("entry: %s", mpvio->auth_info.user_name));
+ DBUG_ASSERT(mpvio->acl_user == 0);
+ mysql_mutex_lock(&acl_cache->lock);
+ for (uint i=0; i < acl_users.elements; i++)
+ {
+ ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*);
+ if ((!acl_user_tmp->user ||
+ !strcmp(mpvio->auth_info.user_name, acl_user_tmp->user)) &&
+ acl_user_tmp->host.compare_hostname(mpvio->host, mpvio->ip))
+ {
+ mpvio->acl_user= acl_user_tmp->copy(mpvio->mem_root);
+
+ /*
+ When setting mpvio->acl_user_plugin we can save memory allocation if
+ this is a built in plugin.
+ */
+ optimize_plugin_compare_by_pointer(&acl_user_tmp->plugin);
+ if (auth_plugin_is_built_in(acl_user_tmp->plugin.str))
+ mpvio->acl_user_plugin= mpvio->acl_user->plugin;
+ else
+ make_lex_string_root(mpvio->mem_root,
+ &mpvio->acl_user_plugin,
+ acl_user_tmp->plugin.str,
+ acl_user_tmp->plugin.length, 0);
+ break;
+ }
+ }
+ mysql_mutex_unlock(&acl_cache->lock);
+
+ if (!mpvio->acl_user)
+ {
+ login_failed_error(mpvio, mpvio->auth_info.password_used);
+ DBUG_RETURN (1);
+ }
+
+ if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ native_password_plugin_name.str) != 0 &&
+ my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ old_password_plugin_name.str) != 0 &&
+ !(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH))
+ {
+ /* user account requires non-default plugin and the client is too old */
+ DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ native_password_plugin_name.str));
+ DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
+ old_password_plugin_name.str));
+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
+ general_log_print(current_thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ DBUG_RETURN (1);
+ }
+
+ mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str;
+ mpvio->auth_info.auth_string_length=
+ (unsigned long) mpvio->acl_user->auth_string.length;
+ strmake(mpvio->auth_info.authenticated_as, mpvio->acl_user->user ?
+ mpvio->acl_user->user : "", USERNAME_LENGTH);
+ DBUG_PRINT("info", ("exit: user=%s, auth_string=%s, authenticated as=%s"
+ ", plugin=%s",
+ mpvio->auth_info.user_name,
+ mpvio->auth_info.auth_string,
+ mpvio->auth_info.authenticated_as,
+ mpvio->acl_user->plugin.str));
+ DBUG_RETURN(0);
+}
+
+
+static bool
+read_client_connect_attrs(char **ptr, size_t *max_bytes_available,
+ const CHARSET_INFO *from_cs)
+{
+ size_t length, length_length;
+ char *ptr_save;
+ /* not enough bytes to hold the length */
+ if (*max_bytes_available < 1)
+ return true;
+
+ /* read the length */
+ ptr_save= *ptr;
+ length= net_field_length_ll((uchar **) ptr);
+ length_length= *ptr - ptr_save;
+ if (*max_bytes_available < length_length)
+ return true;
+
+ *max_bytes_available-= length_length;
+
+ /* length says there're more data than can fit into the packet */
+ if (length > *max_bytes_available)
+ return true;
+
+ /* impose an artificial length limit of 64k */
+ if (length > 65535)
+ return true;
+
+#ifdef HAVE_PSI_THREAD_INTERFACE
+ if (PSI_THREAD_CALL(set_thread_connect_attrs)(*ptr, length, from_cs) && log_warnings)
+ sql_print_warning("Connection attributes of length %lu were truncated",
+ (unsigned long) length);
+#endif
+ return false;
+}
+
+
+static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user)
+{
+#if defined(HAVE_OPENSSL)
+ Vio *vio= thd->net.vio;
+ SSL *ssl= (SSL *) vio->ssl_arg;
+ X509 *cert;
#endif
+ /*
+ At this point we know that user is allowed to connect
+ from given host by given username/password pair. Now
+ we check if SSL is required, if user is using SSL and
+ if X509 certificate attributes are OK
+ */
+ switch (acl_user->ssl_type) {
+ case SSL_TYPE_NOT_SPECIFIED: // Impossible
+ case SSL_TYPE_NONE: // SSL is not required
+ return 0;
+#if defined(HAVE_OPENSSL)
+ case SSL_TYPE_ANY: // Any kind of SSL is ok
+ return vio_type(vio) != VIO_TYPE_SSL;
+ case SSL_TYPE_X509: /* Client should have any valid certificate. */
+ /*
+ Connections with non-valid certificates are dropped already
+ in sslaccept() anyway, so we do not check validity here.
+
+ We need to check for absence of SSL because without SSL
+ we should reject connection.
+ */
+ if (vio_type(vio) == VIO_TYPE_SSL &&
+ SSL_get_verify_result(ssl) == X509_V_OK &&
+ (cert= SSL_get_peer_certificate(ssl)))
+ {
+ X509_free(cert);
+ return 0;
+ }
+ return 1;
+ case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */
+ /* If a cipher name is specified, we compare it to actual cipher in use. */
+ if (vio_type(vio) != VIO_TYPE_SSL ||
+ SSL_get_verify_result(ssl) != X509_V_OK)
+ return 1;
+ if (acl_user->ssl_cipher)
+ {
+ DBUG_PRINT("info", ("comparing ciphers: '%s' and '%s'",
+ acl_user->ssl_cipher, SSL_get_cipher(ssl)));
+ if (strcmp(acl_user->ssl_cipher, SSL_get_cipher(ssl)))
+ {
+ if (log_warnings)
+ sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'",
+ acl_user->ssl_cipher, SSL_get_cipher(ssl));
+ return 1;
+ }
+ }
+ /* Prepare certificate (if exists) */
+ if (!(cert= SSL_get_peer_certificate(ssl)))
+ return 1;
+ /* If X509 issuer is specified, we check it... */
+ if (acl_user->x509_issuer)
+ {
+ char *ptr= X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
+ DBUG_PRINT("info", ("comparing issuers: '%s' and '%s'",
+ acl_user->x509_issuer, ptr));
+ if (strcmp(acl_user->x509_issuer, ptr))
+ {
+ if (log_warnings)
+ sql_print_information("X509 issuer mismatch: should be '%s' "
+ "but is '%s'", acl_user->x509_issuer, ptr);
+ free(ptr);
+ X509_free(cert);
+ return 1;
+ }
+ free(ptr);
+ }
+ /* X509 subject is specified, we check it .. */
+ if (acl_user->x509_subject)
+ {
+ char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
+ DBUG_PRINT("info", ("comparing subjects: '%s' and '%s'",
+ acl_user->x509_subject, ptr));
+ if (strcmp(acl_user->x509_subject, ptr))
+ {
+ if (log_warnings)
+ sql_print_information("X509 subject mismatch: should be '%s' but is '%s'",
+ acl_user->x509_subject, ptr);
+ free(ptr);
+ X509_free(cert);
+ return 1;
+ }
+ free(ptr);
+ }
+ X509_free(cert);
+ return 0;
+#else /* HAVE_OPENSSL */
+ default:
+ /*
+ If we don't have SSL but SSL is required for this user the
+ authentication should fail.
+ */
+ return 1;
+#endif /* HAVE_OPENSSL */
+ }
+ return 1;
+}
+
+
+/* Return true if there is no users that can match the given host */
+
+bool acl_check_host(const char *host, const char *ip)
+{
+ mysql_mutex_lock(&acl_cache->lock);
+ if (allow_all_hosts)
+ {
+
+ mysql_mutex_unlock(&acl_cache->lock);
+ return 0;
+ }
+
+ if ((host && my_hash_search(&acl_check_hosts,(uchar*) host,strlen(host))) ||
+ (ip && my_hash_search(&acl_check_hosts,(uchar*) ip, strlen(ip))))
+ {
+ mysql_mutex_unlock(&acl_cache->lock);
+ return 0; // Found host
+ }
+ for (uint i=0 ; i < acl_wild_hosts.elements ; i++)
+ {
+ ACL_HOST_AND_IP *acl=dynamic_element(&acl_wild_hosts,i,ACL_HOST_AND_IP*);
+ if (acl->compare_hostname(host, ip))
+ {
+ mysql_mutex_unlock(&acl_cache->lock);
+ return 0; // Host ok
+ }
+ }
+ mysql_mutex_unlock(&acl_cache->lock);
+ if (ip != NULL)
+ {
+ /* Increment HOST_CACHE.COUNT_HOST_ACL_ERRORS. */
+ Host_errors errors;
+ errors.m_host_acl= 1;
+ inc_host_errors(ip, &errors);
+ }
+ return 1; // Host is not allowed
+}
+
+
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
+
+
+
+bool Thd_charset_adapter::init_client_charset(uint cs_number)
+{
+ if (thd_init_client_charset(thd, cs_number))
+ return true;
+ thd->update_charset();
+ return thd->is_error();
+}
+
/**
Sets the default default auth plugin value if no option was specified.
@@ -431,124 +768,6 @@ static bool send_plugin_request_packet(M
(uchar*) data, data_len));
}
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-/**
- Finds acl entry in user database for authentication purposes.
-
- Finds a user and copies it into mpvio. Reports an authentication
- failure if a user is not found.
-
- @note find_acl_user is not the same, because it doesn't take into
- account the case when user is not empty, but acl_user->user is empty
-
- @retval 0 found
- @retval 1 not found
-*/
-static bool find_mpvio_user(MPVIO_EXT *mpvio)
-{
- DBUG_ENTER("find_mpvio_user");
- DBUG_PRINT("info", ("entry: %s", mpvio->auth_info.user_name));
- DBUG_ASSERT(mpvio->acl_user == 0);
- mysql_mutex_lock(&acl_cache->lock);
- for (uint i=0; i < acl_users.elements; i++)
- {
- ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*);
- if ((!acl_user_tmp->user ||
- !strcmp(mpvio->auth_info.user_name, acl_user_tmp->user)) &&
- acl_user_tmp->host.compare_hostname(mpvio->host, mpvio->ip))
- {
- mpvio->acl_user= acl_user_tmp->copy(mpvio->mem_root);
-
- /*
- When setting mpvio->acl_user_plugin we can save memory allocation if
- this is a built in plugin.
- */
- optimize_plugin_compare_by_pointer(&acl_user_tmp->plugin);
- if (auth_plugin_is_built_in(acl_user_tmp->plugin.str))
- mpvio->acl_user_plugin= mpvio->acl_user->plugin;
- else
- make_lex_string_root(mpvio->mem_root,
- &mpvio->acl_user_plugin,
- acl_user_tmp->plugin.str,
- acl_user_tmp->plugin.length, 0);
- break;
- }
- }
- mysql_mutex_unlock(&acl_cache->lock);
-
- if (!mpvio->acl_user)
- {
- login_failed_error(mpvio, mpvio->auth_info.password_used);
- DBUG_RETURN (1);
- }
-
- if (my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
- native_password_plugin_name.str) != 0 &&
- my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
- old_password_plugin_name.str) != 0 &&
- !(mpvio->client_capabilities & CLIENT_PLUGIN_AUTH))
- {
- /* user account requires non-default plugin and the client is too old */
- DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
- native_password_plugin_name.str));
- DBUG_ASSERT(my_strcasecmp(system_charset_info, mpvio->acl_user->plugin.str,
- old_password_plugin_name.str));
- my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
- general_log_print(current_thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
- DBUG_RETURN (1);
- }
-
- mpvio->auth_info.auth_string= mpvio->acl_user->auth_string.str;
- mpvio->auth_info.auth_string_length=
- (unsigned long) mpvio->acl_user->auth_string.length;
- strmake(mpvio->auth_info.authenticated_as, mpvio->acl_user->user ?
- mpvio->acl_user->user : "", USERNAME_LENGTH);
- DBUG_PRINT("info", ("exit: user=%s, auth_string=%s, authenticated as=%s"
- ", plugin=%s",
- mpvio->auth_info.user_name,
- mpvio->auth_info.auth_string,
- mpvio->auth_info.authenticated_as,
- mpvio->acl_user->plugin.str));
- DBUG_RETURN(0);
-}
-
-
-static bool
-read_client_connect_attrs(char **ptr, size_t *max_bytes_available,
- const CHARSET_INFO *from_cs)
-{
- size_t length, length_length;
- char *ptr_save;
- /* not enough bytes to hold the length */
- if (*max_bytes_available < 1)
- return true;
-
- /* read the length */
- ptr_save= *ptr;
- length= net_field_length_ll((uchar **) ptr);
- length_length= *ptr - ptr_save;
- if (*max_bytes_available < length_length)
- return true;
-
- *max_bytes_available-= length_length;
-
- /* length says there're more data than can fit into the packet */
- if (length > *max_bytes_available)
- return true;
-
- /* impose an artificial length limit of 64k */
- if (length > 65535)
- return true;
-
-#ifdef HAVE_PSI_THREAD_INTERFACE
- if (PSI_THREAD_CALL(set_thread_connect_attrs)(*ptr, length, from_cs) && log_warnings)
- sql_print_warning("Connection attributes of length %lu were truncated",
- (unsigned long) length);
-#endif
- return false;
-}
-
-#endif
/* the packet format is described in send_change_user_packet() */
static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
@@ -686,7 +905,7 @@ static bool parse_com_change_user_packet
mpvio->cached_client_reply.pkt_len= passwd_len;
mpvio->cached_client_reply.plugin= client_plugin;
mpvio->status= MPVIO_EXT::RESTART;
-#endif
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
DBUG_RETURN (0);
}
@@ -1441,113 +1660,6 @@ static void server_mpvio_info(MYSQL_PLUG
mpvio_info(mpvio->net->vio, info);
}
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user)
-{
-#if defined(HAVE_OPENSSL)
- Vio *vio= thd->net.vio;
- SSL *ssl= (SSL *) vio->ssl_arg;
- X509 *cert;
-#endif
-
- /*
- At this point we know that user is allowed to connect
- from given host by given username/password pair. Now
- we check if SSL is required, if user is using SSL and
- if X509 certificate attributes are OK
- */
- switch (acl_user->ssl_type) {
- case SSL_TYPE_NOT_SPECIFIED: // Impossible
- case SSL_TYPE_NONE: // SSL is not required
- return 0;
-#if defined(HAVE_OPENSSL)
- case SSL_TYPE_ANY: // Any kind of SSL is ok
- return vio_type(vio) != VIO_TYPE_SSL;
- case SSL_TYPE_X509: /* Client should have any valid certificate. */
- /*
- Connections with non-valid certificates are dropped already
- in sslaccept() anyway, so we do not check validity here.
-
- We need to check for absence of SSL because without SSL
- we should reject connection.
- */
- if (vio_type(vio) == VIO_TYPE_SSL &&
- SSL_get_verify_result(ssl) == X509_V_OK &&
- (cert= SSL_get_peer_certificate(ssl)))
- {
- X509_free(cert);
- return 0;
- }
- return 1;
- case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */
- /* If a cipher name is specified, we compare it to actual cipher in use. */
- if (vio_type(vio) != VIO_TYPE_SSL ||
- SSL_get_verify_result(ssl) != X509_V_OK)
- return 1;
- if (acl_user->ssl_cipher)
- {
- DBUG_PRINT("info", ("comparing ciphers: '%s' and '%s'",
- acl_user->ssl_cipher, SSL_get_cipher(ssl)));
- if (strcmp(acl_user->ssl_cipher, SSL_get_cipher(ssl)))
- {
- if (log_warnings)
- sql_print_information("X509 ciphers mismatch: should be '%s' but is '%s'",
- acl_user->ssl_cipher, SSL_get_cipher(ssl));
- return 1;
- }
- }
- /* Prepare certificate (if exists) */
- if (!(cert= SSL_get_peer_certificate(ssl)))
- return 1;
- /* If X509 issuer is specified, we check it... */
- if (acl_user->x509_issuer)
- {
- char *ptr= X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
- DBUG_PRINT("info", ("comparing issuers: '%s' and '%s'",
- acl_user->x509_issuer, ptr));
- if (strcmp(acl_user->x509_issuer, ptr))
- {
- if (log_warnings)
- sql_print_information("X509 issuer mismatch: should be '%s' "
- "but is '%s'", acl_user->x509_issuer, ptr);
- free(ptr);
- X509_free(cert);
- return 1;
- }
- free(ptr);
- }
- /* X509 subject is specified, we check it .. */
- if (acl_user->x509_subject)
- {
- char *ptr= X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
- DBUG_PRINT("info", ("comparing subjects: '%s' and '%s'",
- acl_user->x509_subject, ptr));
- if (strcmp(acl_user->x509_subject, ptr))
- {
- if (log_warnings)
- sql_print_information("X509 subject mismatch: should be '%s' but is '%s'",
- acl_user->x509_subject, ptr);
- free(ptr);
- X509_free(cert);
- return 1;
- }
- free(ptr);
- }
- X509_free(cert);
- return 0;
-#else /* HAVE_OPENSSL */
- default:
- /*
- If we don't have SSL but SSL is required for this user the
- authentication should fail.
- */
- return 1;
-#endif /* HAVE_OPENSSL */
- }
- return 1;
-}
-#endif
-
static int do_auth_once(THD *thd, LEX_STRING *auth_plugin_name,
MPVIO_EXT *mpvio)
@@ -1849,7 +1961,7 @@ acl_authenticate(THD *thd, uint com_chan
" identity %s", auth_user, acl_user->user));
mysql_mutex_unlock(&acl_cache->lock);
}
-#endif
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
sctx->master_access= acl_user->access;
if (acl_user->user)
@@ -1890,7 +2002,7 @@ acl_authenticate(THD *thd, uint com_chan
DBUG_RETURN(1); // The error is set by get_or_create_user_conn()
sctx->password_expired= acl_user->password_expired;
-#endif
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
}
else
sctx->skip_grants();
@@ -2038,7 +2150,7 @@ static int native_password_authenticate(
#ifdef NO_EMBEDDED_ACCESS_CHECKS
DBUG_RETURN(CR_OK);
-#endif
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
DBUG_EXECUTE_IF("native_password_bad_reply",
{
@@ -2084,7 +2196,7 @@ static int old_password_authenticate(MYS
#ifdef NO_EMBEDDED_ACCESS_CHECKS
return CR_OK;
-#endif
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
/*
legacy: if switch_from_long_to_short_scramble,
@@ -2667,3 +2779,4 @@ void check_password_policy(String *passw
plugin_unlock(0, plugin);
}
}
+
=== modified file 'sql/auth/sql_authentication.h'
--- a/sql/auth/sql_authentication.h 2012-09-05 11:40:51 +0000
+++ b/sql/auth/sql_authentication.h 2012-09-06 12:02:23 +0000
@@ -1,18 +1,21 @@
#ifndef SQL_AUTHENTICATION_INCLUDED
#define SQL_AUTHENTICATION_INCLUDED
+#include <mysql/plugin_auth.h> // MYSQL_SERVER_AUTH_INFO
+class ACL_USER;
+
+/* Defines */
+/** Size of the header fields of an authentication packet. */
+#define AUTH_PACKET_HEADER_SIZE_PROTO_41 32
+#define AUTH_PACKET_HEADER_SIZE_PROTO_40 5
+
+
class Thd_charset_adapter
{
THD *thd;
public:
Thd_charset_adapter(THD *thd_arg) : thd (thd_arg) {}
- bool init_client_charset(uint cs_number)
- {
- if (thd_init_client_charset(thd, cs_number))
- return true;
- thd->update_charset();
- return thd->is_error();
- }
+ bool init_client_charset(uint cs_number);
const CHARSET_INFO *charset() { return thd->charset(); }
};
@@ -58,9 +61,8 @@ struct MPVIO_EXT :public MYSQL_PLUGIN_VI
int vio_is_encrypted;
};
-
/**
- Common Data Structures
+ Data Structures
*/
extern LEX_STRING default_auth_plugin_name;
extern LEX_STRING native_password_plugin_name;
@@ -76,8 +78,13 @@ extern plugin_ref native_password_plugin
/**
- Common Functions
+ Prototypes
*/
bool auth_plugin_is_built_in(const char *plugin_name);
+int acl_authenticate(THD *thd, uint com_change_user_pkt_len);
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+bool acl_check_host(const char *host, const char *ip);
+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
#endif /* SQL_AUTHENTICATION_INCLUDED */
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2012-08-21 07:45:27 +0000
+++ b/sql/sql_class.cc 2012-09-06 12:02:23 +0000
@@ -62,6 +62,7 @@
#include "mysqld.h"
#include <mysql/psi/mysql_statement.h>
+#include "sql_authentication.h" // acl_getroot
using std::min;
using std::max;
=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc 2012-07-17 07:52:54 +0000
+++ b/sql/sql_connect.cc 2012-09-06 12:02:23 +0000
@@ -33,6 +33,7 @@
#include "hostname.h" // inc_host_errors, ip_to_hostname,
// reset_host_errors
#include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL
+#include "sql_authentication.h" // acl_authenticate
#include "sql_callback.h"
#include <algorithm>
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2012-08-29 10:31:45 +0000
+++ b/sql/sql_parse.cc 2012-09-06 12:02:23 +0000
@@ -100,6 +100,7 @@
#include "global_threads.h"
#include "sql_analyse.h"
#include "table_cache.h" // table_cache_manager
+#include "sql_authentication.h" // acl_authenticate
#include <algorithm>
using std::max;
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (harin.vadodaria:4418 to 4419) WL#6486 | Harin Vadodaria | 6 Sep |