Merge branch 'release-1.0GA' of https://github.com/mariadb-corporation/MaxScale into release-1.0GA
This commit is contained in:
@ -32,11 +32,13 @@
|
|||||||
* x.y.z.%, x.y.%.%, x.%.%.%
|
* x.y.z.%, x.y.%.%, x.%.%.%
|
||||||
* 03/10/14 Massimiliano Pinto Added netmask to user@host authentication for wildcard in IPv4 hosts
|
* 03/10/14 Massimiliano Pinto Added netmask to user@host authentication for wildcard in IPv4 hosts
|
||||||
* 13/10/14 Massimiliano Pinto Added (user@host)@db authentication
|
* 13/10/14 Massimiliano Pinto Added (user@host)@db authentication
|
||||||
|
* 04/12/14 Massimiliano Pinto Added support for IPv$ wildcard hosts: a.%, a.%.% and a.b.%
|
||||||
*
|
*
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
|
|
||||||
#include <dcb.h>
|
#include <dcb.h>
|
||||||
@ -82,6 +84,7 @@ void resource_free(HASHTABLE *resource);
|
|||||||
void *resource_fetch(HASHTABLE *, char *);
|
void *resource_fetch(HASHTABLE *, char *);
|
||||||
int resource_add(HASHTABLE *, char *, char *);
|
int resource_add(HASHTABLE *, char *, char *);
|
||||||
int resource_hash(char *);
|
int resource_hash(char *);
|
||||||
|
static int normalize_hostname(char *input_host, char *output_host);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the user/passwd form mysql.user table into the service users' hashtable
|
* Load the user/passwd form mysql.user table into the service users' hashtable
|
||||||
@ -217,8 +220,6 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p
|
|||||||
struct sockaddr_in serv_addr;
|
struct sockaddr_in serv_addr;
|
||||||
MYSQL_USER_HOST key;
|
MYSQL_USER_HOST key;
|
||||||
char ret_ip[INET_ADDRSTRLEN + 1]="";
|
char ret_ip[INET_ADDRSTRLEN + 1]="";
|
||||||
int found_range=0;
|
|
||||||
int found_any=0;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (users == NULL || user == NULL || host == NULL) {
|
if (users == NULL || user == NULL || host == NULL) {
|
||||||
@ -255,42 +256,30 @@ int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *p
|
|||||||
/* ANY */
|
/* ANY */
|
||||||
if (strcmp(host, "%") == 0) {
|
if (strcmp(host, "%") == 0) {
|
||||||
strcpy(ret_ip, "0.0.0.0");
|
strcpy(ret_ip, "0.0.0.0");
|
||||||
found_any = 1;
|
key.netmask = 0;
|
||||||
} else {
|
} else {
|
||||||
char *tmp;
|
/* hostname without % wildcards has netmask = 32 */
|
||||||
strncpy(ret_ip, host, INET_ADDRSTRLEN);
|
key.netmask = normalize_hostname(host, ret_ip);
|
||||||
tmp = ret_ip+strlen(ret_ip)-1;
|
|
||||||
|
|
||||||
/* start from Class C */
|
if (key.netmask == -1) {
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
while(tmp > ret_ip) {
|
LOGFILE_ERROR,
|
||||||
if (*tmp == '%') {
|
"Error : strdup() failed in normalize_hostname for %s@%s",
|
||||||
/* set only the last IPv4 byte to 1
|
user,
|
||||||
* avoiding setipadress() failure
|
host)));
|
||||||
* for Class C address
|
|
||||||
*/
|
|
||||||
found_range++;
|
|
||||||
if (found_range == 1)
|
|
||||||
*tmp = '1';
|
|
||||||
else
|
|
||||||
*tmp = '0';
|
|
||||||
}
|
|
||||||
tmp--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill IPv4 data struct */
|
/* fill IPv4 data struct */
|
||||||
if (setipaddress(&serv_addr.sin_addr, ret_ip)) {
|
if (setipaddress(&serv_addr.sin_addr, ret_ip) && strlen(ret_ip)) {
|
||||||
|
|
||||||
/* copy IPv4 data into key.ipv4 */
|
/* copy IPv4 data into key.ipv4 */
|
||||||
memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr));
|
memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr));
|
||||||
|
|
||||||
if (found_range) {
|
/* if netmask < 32 there are % wildcards */
|
||||||
/* let's zero the last IP byte: a.b.c.0 we set above to 1*/
|
if (key.netmask < 32) {
|
||||||
|
/* let's zero the last IP byte: a.b.c.0 we may have set above to 1*/
|
||||||
key.ipv4.sin_addr.s_addr &= 0x00FFFFFF;
|
key.ipv4.sin_addr.s_addr &= 0x00FFFFFF;
|
||||||
key.netmask = 32 - (found_range * 8);
|
|
||||||
} else {
|
|
||||||
key.netmask = 32 - (found_any * 32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add user@host as key and passwd as value in the MySQL users hash table */
|
/* add user@host as key and passwd as value in the MySQL users hash table */
|
||||||
@ -1120,3 +1109,87 @@ resource_fetch(HASHTABLE *resources, char *key)
|
|||||||
return hashtable_fetch(resources, key);
|
return hashtable_fetch(resources, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize hostname with % wildcards to a valid IP string.
|
||||||
|
*
|
||||||
|
* Valid input values:
|
||||||
|
* a.b.c.d, a.b.c.%, a.b.%.%, a.%.%.%
|
||||||
|
* Short formats a.% and a.%.% are both converted to a.%.%.%
|
||||||
|
* Short format a.b.% is converted to a.b.%.%
|
||||||
|
*
|
||||||
|
* Last host byte is set to 1, avoiding setipadress() failure
|
||||||
|
*
|
||||||
|
* @param input_host The hostname with possible % wildcards
|
||||||
|
* @param output_host The normalized hostname (buffer must be preallocated)
|
||||||
|
* @return The calculated netmask or -1 on failure
|
||||||
|
*/
|
||||||
|
static int normalize_hostname(char *input_host, char *output_host)
|
||||||
|
{
|
||||||
|
int netmask, bytes, bits = 0, found_wildcard = 0;
|
||||||
|
char *p, *lasts, *tmp;
|
||||||
|
int useorig = 0;
|
||||||
|
|
||||||
|
output_host[0] = 0;
|
||||||
|
bytes = 0;
|
||||||
|
|
||||||
|
tmp = strdup(input_host);
|
||||||
|
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = strtok_r(tmp, ".", &lasts);
|
||||||
|
while (p != NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (strcmp(p, "%"))
|
||||||
|
{
|
||||||
|
if (! isdigit(*p))
|
||||||
|
useorig = 1;
|
||||||
|
|
||||||
|
strcat(output_host, p);
|
||||||
|
bits += 8;
|
||||||
|
}
|
||||||
|
else if (bytes == 3)
|
||||||
|
{
|
||||||
|
found_wildcard = 1;
|
||||||
|
strcat(output_host, "1");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
found_wildcard = 1;
|
||||||
|
strcat(output_host, "0");
|
||||||
|
}
|
||||||
|
bytes++;
|
||||||
|
p = strtok_r(NULL, ".", &lasts);
|
||||||
|
if (p)
|
||||||
|
strcat(output_host, ".");
|
||||||
|
}
|
||||||
|
if (found_wildcard)
|
||||||
|
{
|
||||||
|
netmask = bits;
|
||||||
|
while (bytes++ < 4)
|
||||||
|
{
|
||||||
|
if (bytes == 4)
|
||||||
|
{
|
||||||
|
strcat(output_host, ".1");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcat(output_host, ".0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
netmask = 32;
|
||||||
|
|
||||||
|
if (useorig == 1)
|
||||||
|
{
|
||||||
|
netmask = 32;
|
||||||
|
strcpy(output_host, input_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
|
return netmask;
|
||||||
|
}
|
||||||
|
@ -392,6 +392,22 @@ int main() {
|
|||||||
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
|
if (!ret) fprintf(stderr, "\t-- Expecting ok\n");
|
||||||
assert(ret == 0);
|
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);
|
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");
|
if (ret) fprintf(stderr, "\t-- Expecting no match\n");
|
||||||
assert(ret == 1);
|
assert(ret == 1);
|
||||||
|
Reference in New Issue
Block a user