
The dbusers.c was a MySQL protocol specific file which was used directly by some of the modules. Added a new return value for the loadusers authenticator entry point which allows fatal failures to occur when users are loaded. Currently this is only taken into notice when the service is first started. If a listener later returns a fatal error, it is only logged but the service stays in operation. Moved the MySQLAuth authenticator sources and the tests that relate to this module into a subdirectory in the authenticator directory. Eventually, all authenticators could have a subdirectory of their own.
547 lines
15 KiB
C
547 lines
15 KiB
C
/*
|
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
|
*
|
|
* Use of this software is governed by the Business Source License included
|
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
|
|
*
|
|
* Change Date: 2019-07-01
|
|
*
|
|
* On the date above, in accordance with the Business Source License, use
|
|
* of this software will be governed by version 2 or later of the General
|
|
* Public License.
|
|
*/
|
|
|
|
/**
|
|
*
|
|
* @verbatim
|
|
* Revision History
|
|
*
|
|
* Date Who Description
|
|
* 14/02/2014 Massimiliano Pinto Initial implementation
|
|
* 17/02/2014 Massimiliano Pinto Added check ipv4
|
|
* 03/10/2014 Massimiliano Pinto Added check for wildcard hosts
|
|
*
|
|
* @endverbatim
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <maxscale/dcb.h>
|
|
#include <maxscale/service.h>
|
|
#include <maxscale/users.h>
|
|
#include <maxscale/log_manager.h>
|
|
#include <maxscale/secrets.h>
|
|
#include "dbusers.h"
|
|
#include <maxscale/protocol/mysql.h>
|
|
#include <mysql_auth.h>
|
|
#include <maxscale/listener.h>
|
|
#include <arpa/inet.h>
|
|
#include <maxscale/alloc.h>
|
|
|
|
extern int setipaddress();
|
|
|
|
int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char *password)
|
|
{
|
|
struct sockaddr_in serv_addr;
|
|
MYSQL_USER_HOST key;
|
|
MYSQL_USER_HOST find_key;
|
|
USERS *mysql_users;
|
|
char ret_ip[200] = "";
|
|
char *fetch_data;
|
|
char *db = "";
|
|
DCB *dcb;
|
|
SERVICE *service;
|
|
SERV_LISTENER dummy;
|
|
unsigned long fix_ipv4;
|
|
|
|
dcb = dcb_alloc(DCB_ROLE_INTERNAL, &dummy);
|
|
|
|
if (dcb == NULL)
|
|
{
|
|
fprintf(stderr, "dcb_alloc() failed\n");
|
|
return 1;
|
|
}
|
|
if ((service = (SERVICE *)MXS_CALLOC(1, sizeof(SERVICE))) == NULL)
|
|
{
|
|
dcb_close(dcb);
|
|
return 1;
|
|
}
|
|
|
|
if (ipv4 > UINT_MAX)
|
|
{
|
|
fix_ipv4 = UINT_MAX;
|
|
}
|
|
else
|
|
{
|
|
fix_ipv4 = ipv4;
|
|
}
|
|
|
|
mysql_users = mysql_users_alloc();
|
|
/* prepare the user@host data struct */
|
|
memset(&key, 0, sizeof(key));
|
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
|
serv_addr.sin_family = AF_INET;
|
|
memcpy(&(serv_addr).sin_addr.s_addr, &fix_ipv4, sizeof(ipv4));
|
|
|
|
key.user = username;
|
|
memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr));
|
|
key.resource = db;
|
|
|
|
inet_ntop(AF_INET, &(serv_addr).sin_addr, ret_ip, INET_ADDRSTRLEN);
|
|
|
|
fprintf(stderr, "IPv4 passed/fixed [%lu/%lu] is [%s]\n", ipv4, fix_ipv4, ret_ip);
|
|
|
|
/* add user@host as key and passwd as value in the MySQL users hash table */
|
|
if (!mysql_users_add(mysql_users, &key, password))
|
|
{
|
|
fprintf(stderr, "Failed adding %s@%s(%lu)\n", username, ret_ip, fix_ipv4);
|
|
users_free(mysql_users);
|
|
MXS_FREE(service);
|
|
dcb_close(dcb);
|
|
return 1;
|
|
}
|
|
|
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
|
memset(&find_key, 0, sizeof(find_key));
|
|
|
|
find_key.user = username;
|
|
memcpy(&(serv_addr).sin_addr.s_addr, &ipv4, sizeof(ipv4));
|
|
find_key.resource = db;
|
|
|
|
memcpy(&find_key.ipv4, &serv_addr, sizeof(serv_addr));
|
|
|
|
fetch_data = mysql_users_fetch(mysql_users, &find_key);
|
|
|
|
users_free(mysql_users);
|
|
MXS_FREE(service);
|
|
dcb_close(dcb);
|
|
|
|
if (!fetch_data)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int set_and_get_single_mysql_users(char *username, char *hostname, char *password)
|
|
{
|
|
struct sockaddr_in serv_addr;
|
|
MYSQL_USER_HOST key;
|
|
USERS *mysql_users;
|
|
char ret_ip[200] = "";
|
|
char *fetch_data;
|
|
char *db = "";
|
|
|
|
mysql_users = mysql_users_alloc();
|
|
|
|
/* prepare the user@host data struct */
|
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
|
memset(&key, 0, sizeof(key));
|
|
|
|
|
|
if (hostname)
|
|
if (!setipaddress(&serv_addr.sin_addr, hostname))
|
|
{
|
|
fprintf(stderr, "setipaddress failed for host [%s]\n", hostname);
|
|
users_free(mysql_users);
|
|
return 1;
|
|
}
|
|
if (username)
|
|
{
|
|
key.user = username;
|
|
}
|
|
|
|
memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr));
|
|
key.resource = db;
|
|
|
|
inet_ntop(AF_INET, &(serv_addr).sin_addr, ret_ip, INET_ADDRSTRLEN);
|
|
|
|
fprintf(stderr, "set/get [%s@%s]: IPV4 %lu is [%u].[%u].[%u].[%u]\n", username, hostname,
|
|
(unsigned long) serv_addr.sin_addr.s_addr, serv_addr.sin_addr.s_addr & 0xFF,
|
|
(serv_addr.sin_addr.s_addr & 0xFF00), (serv_addr.sin_addr.s_addr & 0xFF0000),
|
|
((serv_addr.sin_addr.s_addr & 0xFF000000) / (256 * 256 * 256)));
|
|
|
|
/* add user@host as key and passwd as value in the MySQL users hash table */
|
|
if (!mysql_users_add(mysql_users, &key, password))
|
|
{
|
|
fprintf(stderr, "mysql_users_add() failed for %s@%s\n", username, hostname);
|
|
users_free(mysql_users);
|
|
return 1;
|
|
}
|
|
|
|
memset(&serv_addr, 0, sizeof(serv_addr));
|
|
|
|
if (hostname)
|
|
if (!setipaddress(&serv_addr.sin_addr, hostname))
|
|
{
|
|
fprintf(stderr, "setipaddress failed for host [%s]\n", hostname);
|
|
users_free(mysql_users);
|
|
return 1;
|
|
}
|
|
key.user = username;
|
|
memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr));
|
|
key.resource = db;
|
|
|
|
fetch_data = mysql_users_fetch(mysql_users, &key);
|
|
|
|
users_free(mysql_users);
|
|
|
|
if (!fetch_data)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *password, char *from, char *anydb,
|
|
char *db, char *db_from)
|
|
{
|
|
USERS *mysql_users;
|
|
int ret = -1;
|
|
struct sockaddr_in client_addr;
|
|
DCB *dcb;
|
|
SERVICE *service;
|
|
MYSQL_session *data;
|
|
|
|
if ((service = (SERVICE *)MXS_CALLOC(1, sizeof(SERVICE))) == NULL)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
SERV_LISTENER *port = listener_alloc(service, "testlistener", "MySQLClient", NULL, 4006, "MySQLAuth", NULL, NULL);
|
|
|
|
dcb = dcb_alloc(DCB_ROLE_INTERNAL, port);
|
|
|
|
if (dcb == NULL)
|
|
{
|
|
fprintf(stderr, "dcb_alloc() failed\n");
|
|
return ret;
|
|
}
|
|
|
|
memset(&client_addr, 0, sizeof(client_addr));
|
|
|
|
if (hostname)
|
|
{
|
|
if (!setipaddress(&client_addr.sin_addr, from))
|
|
{
|
|
fprintf(stderr, "setipaddress failed for host [%s]\n", from);
|
|
MXS_FREE(service);
|
|
dcb_close(dcb);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
if ((data = (MYSQL_session *) MXS_CALLOC(1, sizeof(MYSQL_session))) == NULL)
|
|
{
|
|
MXS_FREE(service);
|
|
dcb_close(dcb);
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* client IPv4 in raw data*/
|
|
memcpy(&dcb->ipv4, (struct sockaddr_in *)&client_addr, sizeof(struct sockaddr_in));
|
|
|
|
dcb->service = service;
|
|
|
|
mysql_users = mysql_users_alloc();
|
|
|
|
service->ports = port;
|
|
service->ports->users = mysql_users;
|
|
|
|
if (db_from != NULL)
|
|
{
|
|
strcpy(data->db, db_from);
|
|
}
|
|
else
|
|
{
|
|
data->db[0] = 0;
|
|
}
|
|
|
|
/* freed by dcb_close(dcb) */
|
|
dcb->data = data;
|
|
|
|
// the routine returns 1 on success
|
|
if (anydb != NULL)
|
|
{
|
|
if (strcmp(anydb, "N") == 0)
|
|
{
|
|
ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password, anydb, db);
|
|
}
|
|
else if (strcmp(anydb, "Y") == 0)
|
|
{
|
|
ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password, "Y", "");
|
|
}
|
|
else
|
|
{
|
|
ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password, "N", NULL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password, "N", NULL);
|
|
}
|
|
|
|
if (ret == 0)
|
|
{
|
|
fprintf(stderr, "add_mysql_users_with_host_ipv4 (%s@%s, %s) FAILED\n", username, hostname, password);
|
|
}
|
|
else
|
|
{
|
|
unsigned char db_passwd[100] = "";
|
|
|
|
dcb->remote = MXS_STRDUP_A(from);
|
|
|
|
// returns 0 on success
|
|
ret = gw_find_mysql_user_password_sha1(username, db_passwd, dcb);
|
|
}
|
|
|
|
users_free(mysql_users);
|
|
MXS_FREE(service);
|
|
dcb_close(dcb);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int ret;
|
|
int i = 0;
|
|
int k = 0;
|
|
time_t t;
|
|
|
|
fprintf(stderr, "----------------\n");
|
|
|
|
time(&t);
|
|
fprintf(stderr, "%s\n", asctime(localtime(&t)));
|
|
fprintf(stderr, ">>> Started MySQL load, set & get users@host\n");
|
|
|
|
|
|
ret = set_and_get_single_mysql_users("pippo", "localhost", "xyz");
|
|
assert(ret == 0);
|
|
ret = set_and_get_single_mysql_users("pippo", "127.0.0.2", "xyz");
|
|
assert(ret == 0);
|
|
ret = set_and_get_single_mysql_users("pippo", "%", "xyz");
|
|
assert(ret == 1);
|
|
ret = set_and_get_single_mysql_users("rootuser", NULL, "wwwww");
|
|
assert(ret == 0);
|
|
ret = set_and_get_single_mysql_users("nullpwd", "this_host_does_not_exists", NULL);
|
|
assert(ret == 1);
|
|
ret = set_and_get_single_mysql_users("myuser", "345.-1.5.40997", "password");
|
|
assert(ret == 1);
|
|
ret = set_and_get_single_mysql_users(NULL, NULL, NULL);
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_single_mysql_users_ipv4("negative", -467295, "_ncd");
|
|
assert(ret == 1);
|
|
ret = set_and_get_single_mysql_users_ipv4("extra", 0xFFFFFFFFFUL * 100, "JJcd");
|
|
assert(ret == 1);
|
|
ret = set_and_get_single_mysql_users_ipv4("aaapo", 0, "JJcd");
|
|
assert(ret == 0);
|
|
ret = set_and_get_single_mysql_users_ipv4(NULL, '\0', "JJcd");
|
|
assert(ret == 1);
|
|
|
|
|
|
for (i = 256 * 256 * 256; i <= 256 * 256 * 256 + 5; i++)
|
|
{
|
|
char user[129] = "";
|
|
snprintf(user, 128, "user_%i", k);
|
|
ret = set_and_get_single_mysql_users_ipv4(user, i, "JJcd");
|
|
assert(ret == 0);
|
|
k++;
|
|
}
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "%", "one", "127.0.0.1", NULL, NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "%", "", "127.0.0.1", NULL, NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "%", "two", "192.168.2.2", NULL, NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.168.4.%", "ffoo", "192.168.2.2", NULL, NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.168.%.%", "foo", "192.168.2.2", NULL, NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.68.0.2", NULL, NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.0.0.2", "Y", NULL, "cossa");
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
fprintf(stderr, "Adding pippo, 192.%%.%%.%%, foo, 192.0.0.2, N, NULL, ragione\n");
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.0.0.2", "N", NULL, "ragione");
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.%.%", "foo", "192.2.0.2", NULL, NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.1", "foo", "192.0.0.2", NULL, NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.%.%", "foo", "192.1.0.2", NULL, NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.%", "foo", "192.3.2.1", NULL, NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.0.%.%", "foo", "192.3.2.1", "Y", NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.254.254.245", "N", "matto",
|
|
"matto");
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.254.254.245", "N", "matto",
|
|
"fatto");
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.254.254.245", "Y", "matto",
|
|
"fatto");
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.254.254.245", "Y", "", "fto");
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.254.254.245", "Y", NULL, "grewao");
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.254.254.242", NULL, NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%", "foo", "192.254.254.242", NULL, NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%", "foo", "192.254.254.242", NULL, NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.254.%", "foo", "192.254.254.242", NULL, NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.254.%", "foo", "192.254.0.242", NULL, NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("riccio", "192.0.0.%", "foo", "192.134.0.2", NULL, NULL, NULL);
|
|
if (ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting no match\n");
|
|
}
|
|
assert(ret == 1);
|
|
|
|
ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "12345678901234567890123456789012345678901234",
|
|
"192.254.254.245", "Y", NULL, NULL);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "\t-- Expecting ok\n");
|
|
}
|
|
assert(ret == 0);
|
|
|
|
fprintf(stderr, "----------------\n");
|
|
fprintf(stderr, "<<< Test completed\n");
|
|
|
|
time(&t);
|
|
fprintf(stderr, "%s\n", asctime(localtime(&t)));
|
|
|
|
return 0;
|
|
}
|
|
|