Fix hostname resolution in MySQLAuth

The hostname resolution was broken by the move to IPv6.
This commit is contained in:
Markus Mäkelä
2017-03-06 14:00:06 +02:00
parent 66ba7f3c80
commit 894679d611

View File

@ -53,7 +53,7 @@ static int get_users(SERV_LISTENER *listener);
static MYSQL *gw_mysql_init(void); static MYSQL *gw_mysql_init(void);
static int gw_mysql_set_timeouts(MYSQL* handle); static int gw_mysql_set_timeouts(MYSQL* handle);
static char *mysql_format_user_entry(void *data); static char *mysql_format_user_entry(void *data);
static bool get_hostname(const char *ip_address, char *client_hostname); static bool get_hostname(DCB *dcb, char *client_hostname, size_t size);
static char* get_new_users_query(const char *server_version, bool include_root) static char* get_new_users_query(const char *server_version, bool include_root)
{ {
@ -208,7 +208,8 @@ int validate_mysql_user(sqlite3 *handle, DCB *dcb, MYSQL_session *session,
* as a last resort so we avoid the high cost of the DNS lookup. * as a last resort so we avoid the high cost of the DNS lookup.
*/ */
char client_hostname[MYSQL_HOST_MAXLEN]; char client_hostname[MYSQL_HOST_MAXLEN];
get_hostname(dcb->remote, client_hostname); get_hostname(dcb, client_hostname, sizeof(client_hostname) - 1);
sprintf(sql, mysqlauth_validate_user_query, session->user, client_hostname, sprintf(sql, mysqlauth_validate_user_query, session->user, client_hostname,
client_hostname, session->db, session->db); client_hostname, session->db, session->db);
@ -611,30 +612,27 @@ bool check_service_permissions(SERVICE* service)
* *
* @return True if the hostname query was successful * @return True if the hostname query was successful
*/ */
static bool get_hostname(const char *ip_address, char *client_hostname) static bool get_hostname(DCB *dcb, char *client_hostname, size_t size)
{ {
/* Looks like the parameters are valid. First, convert the client IP string struct addrinfo *ai = NULL, hint = {};
* to binary form. This is somewhat silly, since just a while ago we had the hint.ai_flags = AI_ALL;
* binary address but had to zero it. dbusers.c should be refactored to fix this. int rc;
*/
struct sockaddr_in bin_address; if ((rc = getaddrinfo(dcb->remote, NULL, &hint, &ai)) != 0)
bin_address.sin_family = AF_INET;
if (inet_pton(bin_address.sin_family, ip_address, &(bin_address.sin_addr)) != 1)
{ {
MXS_ERROR("Could not convert to binary ip-address: '%s'.", ip_address); MXS_ERROR("Failed to obtain address for host %s, %s",
dcb->remote, gai_strerror(rc));
return false; return false;
} }
/* Try to lookup the domain name of the given IP-address. This is a slow /* Try to lookup the domain name of the given IP-address. This is a slow
* i/o-operation, which will stall the entire thread. TODO: cache results * i/o-operation, which will stall the entire thread. TODO: cache results
* if this feature is used often. * if this feature is used often. */
*/ int lookup_result = getnameinfo(ai->ai_addr, ai->ai_addrlen,
MXS_DEBUG("Resolving '%s'", ip_address); client_hostname, size,
int lookup_result = getnameinfo((struct sockaddr*)&bin_address,
sizeof(struct sockaddr_in),
client_hostname, sizeof(client_hostname),
NULL, 0, // No need for the port NULL, 0, // No need for the port
NI_NAMEREQD); // Text address only NI_NAMEREQD); // Text address only
freeaddrinfo(ai);
if (lookup_result != 0) if (lookup_result != 0)
{ {
@ -646,7 +644,7 @@ static bool get_hostname(const char *ip_address, char *client_hostname)
MXS_DEBUG("IP-lookup success, hostname is: '%s'", client_hostname); MXS_DEBUG("IP-lookup success, hostname is: '%s'", client_hostname);
} }
return false; return lookup_result == 0;
} }
void start_sqlite_transaction(sqlite3 *handle) void start_sqlite_transaction(sqlite3 *handle)