From 717f24ce4898bd228a5bb2c906b6cbf34f82041b Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Thu, 25 Sep 2014 13:08:12 +0200 Subject: [PATCH 01/39] Added first support for user@x.y.z.% Added first support for user@x.y.z.% --- server/core/dbusers.c | 50 +++++++++++++++++++------- server/modules/protocol/mysql_common.c | 32 +++++++++++------ 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 4f8de392b..5bb8bc320 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -313,29 +313,53 @@ getUsers(SERVICE *service, struct users *users) char ret_ip[INET_ADDRSTRLEN + 1]=""; const char *rc; + int found_range=0; + int found_any=0; /* prepare the user@host data struct */ memset(&serv_addr, 0, sizeof(serv_addr)); memset(&key, 0, sizeof(key)); - /* if host == '%', 0 is passed */ - if (setipaddress(&serv_addr.sin_addr, strcmp(row[1], "%") ? row[1] : "0.0.0.0")) { + /* set user */ + key.user = strdup(row[0]); - key.user = strdup(row[0]); + if(key.user == NULL) { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "%lu [getUsers()] strdup() failed for user %s", + pthread_self(), + row[0]))); - if(key.user == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [getUsers()] strdup() failed for user %s", - pthread_self(), - row[0]))); + continue; + } - continue; + /* handle ANY, Class C */ + + /* if host == '%', 0 serv_addrkeeps its 0 */ + if (strcmp(row[1], "%") == 0) { + strcpy(ret_ip, "0.0.0.0"); + found_any = 1; + } else { + char *tmp; + strcpy(ret_ip, row[1]); + if ((tmp = strrchr(ret_ip, '%')) != NULL) { + // found class C + found_range = 1; + // set fake 1 + *tmp = '1'; } + } + + if (setipaddress(&serv_addr.sin_addr, ret_ip)) { memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr)); - - rc = inet_ntop(AF_INET, &(serv_addr).sin_addr, ret_ip, INET_ADDRSTRLEN); + + if (found_range) { + /* let's zero the last IP byte: a.b.c.0 */ + key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; + } + + rc = inet_ntop(AF_INET, &(key.ipv4).sin_addr, ret_ip, INET_ADDRSTRLEN); /* add user@host as key and passwd as value in the MySQL users hash table */ if (mysql_users_add(users, &key, strlen(row[2]) ? row[2]+1 : row[2])) { @@ -563,6 +587,8 @@ char *mysql_format_user_entry(void *data) if (entry->ipv4.sin_addr.s_addr == INADDR_ANY) { snprintf(mysql_user, mysql_user_len, "%s@%%", entry->user); + } else if ( (entry->ipv4.sin_addr.s_addr & 0xFF000000) == 0) { + snprintf(mysql_user, mysql_user_len, "%s@%i.%i.%i.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256), (entry->ipv4.sin_addr.s_addr & 0x00FF0000) / (256 * 256)); } else { strncpy(mysql_user, entry->user, MYSQL_USER_MAXLEN); strcat(mysql_user, "@"); diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 78e82cb86..280b07708 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -34,7 +34,6 @@ * */ -#include #include "mysql_client_server_protocol.h" #include #include @@ -742,7 +741,6 @@ int gw_do_connect_to_backend( struct sockaddr_in serv_addr; int rv; int so = 0; - int bufsize; memset(&serv_addr, 0, sizeof serv_addr); serv_addr.sin_family = AF_INET; @@ -766,10 +764,6 @@ int gw_do_connect_to_backend( /* prepare for connect */ setipaddress(&serv_addr.sin_addr, host); serv_addr.sin_port = htons(port); - bufsize = GW_CLIENT_SO_SNDBUF; - setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); - bufsize = GW_CLIENT_SO_RCVBUF; - setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); /* set socket to as non-blocking here */ setnonblocking(so); rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); @@ -1350,6 +1344,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, user_password = mysql_users_fetch(service->users, &key); if (!user_password) { + int lastbyte=0; /* The user is not authenticated @ current host */ /* 1) Check for localhost first. @@ -1368,16 +1363,33 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, return 1; } - - /* 2) Continue and check for wildcard host, user@% + + /* + * 2) try class C + * continue to wildcard if no match + */ + lastbyte = key.ipv4.sin_addr.s_addr & 0xFF000000; + + key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; + + user_password = mysql_users_fetch(service->users, &key); + + if (user_password) { + if (strlen(user_password)) + gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + + return 0; + } + + /* 3) Continue and check for wildcard host, user@% * Return 1 if no match */ memset(&key.ipv4, 0, sizeof(struct sockaddr_in)); - LOGIF(LD, + LOGIF(LE, (skygw_log_write_flush( - LOGFILE_DEBUG, + LOGFILE_ERROR, "%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]", pthread_self(), key.user, From 3fdfc5db8d877cff5734bba3506e49da11284477 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Thu, 25 Sep 2014 13:13:52 +0200 Subject: [PATCH 02/39] Code cleanup Code cleanup --- server/modules/protocol/mysql_common.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 280b07708..8473e365b 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -34,6 +34,7 @@ * */ +#include #include "mysql_client_server_protocol.h" #include #include @@ -741,6 +742,7 @@ int gw_do_connect_to_backend( struct sockaddr_in serv_addr; int rv; int so = 0; + int bufsize; memset(&serv_addr, 0, sizeof serv_addr); serv_addr.sin_family = AF_INET; @@ -764,6 +766,10 @@ int gw_do_connect_to_backend( /* prepare for connect */ setipaddress(&serv_addr.sin_addr, host); serv_addr.sin_port = htons(port); + bufsize = GW_CLIENT_SO_SNDBUF; + setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); + bufsize = GW_CLIENT_SO_RCVBUF; + setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); /* set socket to as non-blocking here */ setnonblocking(so); rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); @@ -1387,9 +1393,9 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, memset(&key.ipv4, 0, sizeof(struct sockaddr_in)); - LOGIF(LE, + LOGIF(LD, (skygw_log_write_flush( - LOGFILE_ERROR, + LOGFILE_DEBUG, "%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]", pthread_self(), key.user, From a11303bd5891be8b8dc4a6c70174c45be21eb9a7 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Mon, 29 Sep 2014 10:31:04 +0200 Subject: [PATCH 03/39] wildcard in host printed via show dbusers wildcard in host printed via show dbusers --- server/core/dbusers.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 5bb8bc320..c0aedeef9 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -589,6 +589,10 @@ char *mysql_format_user_entry(void *data) snprintf(mysql_user, mysql_user_len, "%s@%%", entry->user); } else if ( (entry->ipv4.sin_addr.s_addr & 0xFF000000) == 0) { snprintf(mysql_user, mysql_user_len, "%s@%i.%i.%i.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256), (entry->ipv4.sin_addr.s_addr & 0x00FF0000) / (256 * 256)); + } else if ( (entry->ipv4.sin_addr.s_addr & 0xFFFF0000) == 0) { + snprintf(mysql_user, mysql_user_len, "%s@%i.%i.%%.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256)); + } else if ( (entry->ipv4.sin_addr.s_addr & 0xFFFFFF00) == 0) { + snprintf(mysql_user, mysql_user_len, "%s@%i.%%.%%.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF); } else { strncpy(mysql_user, entry->user, MYSQL_USER_MAXLEN); strcat(mysql_user, "@"); From 76320c056ba17db8b642fe67490f183657086ddc Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Mon, 29 Sep 2014 12:08:10 +0200 Subject: [PATCH 04/39] Match Class C,B,A addresses Match Class C,B,A addresses --- server/core/dbusers.c | 28 +++++++++++++++++------- server/modules/protocol/mysql_common.c | 30 ++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 12 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index c0aedeef9..679e7da99 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -333,7 +333,7 @@ getUsers(SERVICE *service, struct users *users) continue; } - /* handle ANY, Class C */ + /* handle ANY, Class C,B,A */ /* if host == '%', 0 serv_addrkeeps its 0 */ if (strcmp(row[1], "%") == 0) { @@ -342,20 +342,32 @@ getUsers(SERVICE *service, struct users *users) } else { char *tmp; strcpy(ret_ip, row[1]); - if ((tmp = strrchr(ret_ip, '%')) != NULL) { - // found class C - found_range = 1; - // set fake 1 - *tmp = '1'; + tmp = ret_ip+strlen(ret_ip); + + while(tmp) { + if (tmp == ‘%’) { + /* set last byte only to 1 + * avoiding setipadress failure + * for Class C address + */ + if (found_range == 1) + *tmp = ‘1’; + else + *tmp = ‘0’; + + found_range++; + } + tmp--; } - } + + } if (setipaddress(&serv_addr.sin_addr, ret_ip)) { memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr)); if (found_range) { - /* let's zero the last IP byte: a.b.c.0 */ + /* let's zero the last IP byte: a.b.c.0 we set above to 1*/ key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; } diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 0475c5b2d..f96e3ec9b 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -1350,7 +1350,6 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, user_password = mysql_users_fetch(service->users, &key); if (!user_password) { - int lastbyte=0; /* The user is not authenticated @ current host */ /* 1) Check for localhost first. @@ -1371,11 +1370,10 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, } /* - * 2) try class C - * continue to wildcard if no match + * 2) try class C,B,A */ - lastbyte = key.ipv4.sin_addr.s_addr & 0xFF000000; + // Class C key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; user_password = mysql_users_fetch(service->users, &key); @@ -1387,6 +1385,30 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, return 0; } + // Class B + key.ipv4.sin_addr.s_addr &= 0x0000FFFF; + + user_password = mysql_users_fetch(service->users, &key); + + if (user_password) { + if (strlen(user_password)) + gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + + return 0; + } + + // Class A + key.ipv4.sin_addr.s_addr &= 0x000000FF; + + user_password = mysql_users_fetch(service->users, &key); + + if (user_password) { + if (strlen(user_password)) + gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + + return 0; + } + /* 3) Continue and check for wildcard host, user@% * Return 1 if no match */ From 2268bf89aacc3570b5db919477aaffe5214fe6e1 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Mon, 29 Sep 2014 12:41:15 +0200 Subject: [PATCH 05/39] Fixed wrong chars Fixed wrong chars --- server/core/dbusers.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 679e7da99..867a9c985 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -345,15 +345,15 @@ getUsers(SERVICE *service, struct users *users) tmp = ret_ip+strlen(ret_ip); while(tmp) { - if (tmp == ‘%’) { + if (tmp == '%') { /* set last byte only to 1 * avoiding setipadress failure * for Class C address */ if (found_range == 1) - *tmp = ‘1’; + *tmp = '1'; else - *tmp = ‘0’; + *tmp = '0'; found_range++; } From 42d0b3c743ebe61ef0ff19486a6a0eb2f7aa8012 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Mon, 29 Sep 2014 13:02:06 +0200 Subject: [PATCH 06/39] Fix for % detection Fix for % detection --- server/core/dbusers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 867a9c985..45251e4d6 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -344,8 +344,8 @@ getUsers(SERVICE *service, struct users *users) strcpy(ret_ip, row[1]); tmp = ret_ip+strlen(ret_ip); - while(tmp) { - if (tmp == '%') { + while(*tmp) { + if (*tmp == '%') { /* set last byte only to 1 * avoiding setipadress failure * for Class C address From 5f6d04e7db87f56e5c386b6acb656bcb0ce0e944 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Mon, 29 Sep 2014 16:50:21 +0200 Subject: [PATCH 07/39] Match for Class C,B,A in hosts with % Match for Class C,B,A in hosts with % --- server/core/dbusers.c | 8 ++++---- server/modules/protocol/mysql_common.c | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 45251e4d6..0e97aa70b 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -28,6 +28,8 @@ * 06/02/2014 Massimiliano Pinto Mysql user root selected based on configuration flag * 26/02/2014 Massimiliano Pinto Addd: replace_mysql_users() routine may replace users' table based on a checksum * 28/02/2014 Massimiliano Pinto Added Mysql user@host authentication + * 29/07/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts: + * x.y.z.%, x.y.%.%, x.%.%.% * * @endverbatim */ @@ -342,7 +344,7 @@ getUsers(SERVICE *service, struct users *users) } else { char *tmp; strcpy(ret_ip, row[1]); - tmp = ret_ip+strlen(ret_ip); + tmp = ret_ip+strlen(ret_ip)-1; while(*tmp) { if (*tmp == '%') { @@ -350,16 +352,14 @@ getUsers(SERVICE *service, struct users *users) * avoiding setipadress failure * for Class C address */ + found_range++; if (found_range == 1) *tmp = '1'; else *tmp = '0'; - - found_range++; } tmp--; } - } if (setipaddress(&serv_addr.sin_addr, ret_ip)) { diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index f96e3ec9b..1cc43fcc4 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -31,6 +31,8 @@ * localhost entry should be added for the selected user in the backends. * Setting to 1 allow localhost (127.0.0.1 or socket) to match the any host grant via * user@% + * 29/07/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts: + * x.y.z.%, x.y.%.%, x.%.%.% * */ @@ -1382,6 +1384,8 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, if (strlen(user_password)) gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + fprintf(stderr, "+++ Matched Class C for %s\n", dcb->remote); + return 0; } @@ -1394,6 +1398,8 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, if (strlen(user_password)) gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + fprintf(stderr, "++ Matched Class B for %s\n", dcb->remote); + return 0; } @@ -1406,6 +1412,8 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, if (strlen(user_password)) gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + fprintf(stderr, "+ Matched Class A for %s\n", dcb->remote); + return 0; } @@ -1438,6 +1446,8 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, dcb->remote))); return 1; } + + fprintf(stderr, "%% Matched ANY for %s\n", dcb->remote); } /* user@host found: now check the password From c3dd8d973a6eddcdd602aa7d4085a4ee54401b76 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Tue, 30 Sep 2014 13:19:03 +0200 Subject: [PATCH 08/39] Code cleanup Code cleanup --- server/modules/protocol/mysql_common.c | 194 ++++++++++++------------- 1 file changed, 97 insertions(+), 97 deletions(-) diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 1cc43fcc4..1c16e2a28 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -1348,119 +1348,119 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, key.user, dcb->remote))); - /* look for user@current_host now */ + /* look for user@current_ipv4 now */ user_password = mysql_users_fetch(service->users, &key); if (!user_password) { - /* The user is not authenticated @ current host */ + /* The user is not authenticated @ current IPv4 */ - /* 1) Check for localhost first. - * The check for localhost is 127.0.0.1 (IPv4 only) - */ - - if ((key.ipv4.sin_addr.s_addr == 0x0100007F) && !dcb->service->localhost_match_wildcard_host) { - /* Skip the wildcard check and return 1 */ - LOGIF(LE, - (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [MySQL Client Auth], user [%s@%s] not found, please try with 'localhost_match_wildcard_host=1' in service definition", - pthread_self(), - key.user, - dcb->remote))); - - return 1; - } - - /* - * 2) try class C,B,A - */ - - // Class C - key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; - - user_password = mysql_users_fetch(service->users, &key); - - if (user_password) { - if (strlen(user_password)) - gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); - - fprintf(stderr, "+++ Matched Class C for %s\n", dcb->remote); - - return 0; - } - - // Class B - key.ipv4.sin_addr.s_addr &= 0x0000FFFF; - - user_password = mysql_users_fetch(service->users, &key); - - if (user_password) { - if (strlen(user_password)) - gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); - - fprintf(stderr, "++ Matched Class B for %s\n", dcb->remote); - - return 0; - } - - // Class A - key.ipv4.sin_addr.s_addr &= 0x000000FF; - - user_password = mysql_users_fetch(service->users, &key); - - if (user_password) { - if (strlen(user_password)) - gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); - - fprintf(stderr, "+ Matched Class A for %s\n", dcb->remote); - - return 0; - } - - /* 3) Continue and check for wildcard host, user@% - * Return 1 if no match - */ - - memset(&key.ipv4, 0, sizeof(struct sockaddr_in)); - - LOGIF(LD, - (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]", - pthread_self(), - key.user, - dcb->remote))); - - user_password = mysql_users_fetch(service->users, &key); - - if (!user_password) { - /* the user@% was not found. - * Return 1 + while (1) { + /* + * (1) Check for localhost first: 127.0.0.1 (IPv4 only) */ + + if ((key.ipv4.sin_addr.s_addr == 0x0100007F) && !dcb->service->localhost_match_wildcard_host) { + /* Skip the wildcard check and return 1 */ + LOGIF(LE, + (skygw_log_write_flush( + LOGFILE_ERROR, + "%lu [MySQL Client Auth], user [%s@%s] not found, please try with 'localhost_match_wildcard_host=1' in service definition", + pthread_self(), + key.user, + dcb->remote))); + + break; + } + + /* + * (2) check for possible IPv4 class C,B,A networks + */ + + /* Class C check */ + key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; + + user_password = mysql_users_fetch(service->users, &key); + + if (user_password) { + fprintf(stderr, "+++ Matched Class C for %s\n", dcb->remote); + + break; + } + + /* Class B check */ + key.ipv4.sin_addr.s_addr &= 0x0000FFFF; + + user_password = mysql_users_fetch(service->users, &key); + + if (user_password) { + fprintf(stderr, "++ Matched Class B for %s\n", dcb->remote); + + break; + } + + /* Class A check */ + key.ipv4.sin_addr.s_addr &= 0x000000FF; + + user_password = mysql_users_fetch(service->users, &key); + + if (user_password) { + fprintf(stderr, "+ Matched Class A for %s\n", dcb->remote); + + break; + } + + /* + * (3) Continue check for wildcard host, user@% + */ + + memset(&key.ipv4, 0, sizeof(struct sockaddr_in)); + LOGIF(LD, (skygw_log_write_flush( LOGFILE_DEBUG, - "%lu [MySQL Client Auth], user [%s@%s] not existent", + "%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]", pthread_self(), key.user, dcb->remote))); - return 1; - } - fprintf(stderr, "%% Matched ANY for %s\n", dcb->remote); + user_password = mysql_users_fetch(service->users, &key); + + if (!user_password) { + /* + * the user@% has not been found. + */ + + LOGIF(LD, + (skygw_log_write_flush( + LOGFILE_DEBUG, + "%lu [MySQL Client Auth], user [%s@%s] not existent", + pthread_self(), + key.user, + dcb->remote))); + break; + } + + fprintf(stderr, "%% Matched ANY for %s\n", dcb->remote); + + break; + } } - /* user@host found: now check the password - * - * Convert the hex data (40 bytes) to binary (20 bytes). - * The gateway_password represents the SHA1(SHA1(real_password)). - * Please note: the real_password is unknown and SHA1(real_password) is unknown as well - */ + /* If user@host has been found we get the the password in binary format*/ + if (user_password) { + /* + * Convert the hex data (40 bytes) to binary (20 bytes). + * The gateway_password represents the SHA1(SHA1(real_password)). + * Please note: the real_password is unknown and SHA1(real_password) is unknown as well + */ - if (strlen(user_password)) - gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + if (strlen(user_password)) + gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); - return 0; + return 0; + } else { + return 1; + } } /** From dbe078f3589f4a548c1c66dcc7268a19b34c100a Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Fri, 3 Oct 2014 17:26:41 +0200 Subject: [PATCH 09/39] MySQL Authentication with wildcards in hosts MySQL Authentication: Added support for wildcards in hosts: a.b.c.% a.b.%.% a.%.%.% --- server/core/dbusers.c | 224 ++++++++++++++----------- server/core/test/CMakeLists.txt | 3 + server/core/test/makefile.mysql_users | 32 ---- server/core/test/test_mysql_users.c | 117 ++++++++++++- server/include/dbusers.h | 3 + server/modules/protocol/mysql_common.c | 34 ++-- 6 files changed, 260 insertions(+), 153 deletions(-) delete mode 100644 server/core/test/makefile.mysql_users diff --git a/server/core/dbusers.c b/server/core/dbusers.c index a5f8f637f..cee42e74a 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -28,8 +28,9 @@ * 06/02/2014 Massimiliano Pinto Mysql user root selected based on configuration flag * 26/02/2014 Massimiliano Pinto Addd: replace_mysql_users() routine may replace users' table based on a checksum * 28/02/2014 Massimiliano Pinto Added Mysql user@host authentication - * 29/07/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts: + * 29/09/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts: * x.y.z.%, x.y.%.%, x.%.%.% + * 03/10/14 Massimiliano Pinto Added netmask to user@host authentication for wildcard in IPv4 hosts * * @endverbatim */ @@ -52,13 +53,14 @@ extern int lm_enabled_logfiles_bitmask; -static int getUsers(SERVICE *service, struct users *users); +static int getUsers(SERVICE *service, USERS *users); static int uh_cmpfun( void* v1, void* v2); static void *uh_keydup(void* key); static void uh_keyfree( void* key); static int uh_hfun( void* key); char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key); char *mysql_format_user_entry(void *data); +int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd); /** * Load the user/passwd form mysql.user table into the service users' hashtable @@ -84,7 +86,7 @@ int reload_mysql_users(SERVICE *service) { int i; -struct users *newusers, *oldusers; +USERS *newusers, *oldusers; if ((newusers = mysql_users_alloc()) == NULL) return 0; @@ -110,7 +112,7 @@ int replace_mysql_users(SERVICE *service) { int i; -struct users *newusers, *oldusers; +USERS *newusers, *oldusers; if ((newusers = mysql_users_alloc()) == NULL) return -1; @@ -150,6 +152,92 @@ struct users *newusers, *oldusers; return i; } + +/** + * Add a new MySQL user with host, password and netmask into the service users table + * + * The netmask values are: + * 0 for any, 32 for single IPv4 + * 24 for a class C from a.b.c.%, 16 for a Class B from a.b.%.% and 8 for a Class A from a.%.%.% + * + * @param users The users table + * @param user The user name + * @param host The host to add, with possible wildcards + * @param passwd The sha1(sha1(passoword)) to add + * @return 1 on success, 0 on failure + */ + +int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd) { + struct sockaddr_in serv_addr; + MYSQL_USER_HOST key; + char ret_ip[INET_ADDRSTRLEN + 1]=""; + int found_range=0; + int found_any=0; + int ret = 0; + + /* prepare the user@host data struct */ + memset(&serv_addr, 0, sizeof(serv_addr)); + memset(&key, 0, sizeof(key)); + + /* set user */ + key.user = strdup(user); + + if(key.user == NULL) { + return ret; + } + + /* handle ANY, Class C,B,A */ + + /* ANY */ + if (strcmp(host, "%") == 0) { + strcpy(ret_ip, "0.0.0.0"); + found_any = 1; + } else { + char *tmp; + strcpy(ret_ip, host); + tmp = ret_ip+strlen(ret_ip)-1; + + /* start from Class C */ + while(*tmp) { + if (*tmp == '%') { + /* set only the last IPv4 byte to 1 + * avoiding setipadress() failure + * for Class C address + */ + found_range++; + if (found_range == 1) + *tmp = '1'; + else + *tmp = '0'; + } + tmp--; + } + } + + /* fill IPv4 data struct */ + if (setipaddress(&serv_addr.sin_addr, ret_ip)) { + + /* copy IPv4 data into key.ipv4 */ + memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr)); + + if (found_range) { + /* let's zero the last IP byte: a.b.c.0 we set above to 1*/ + 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 */ + if (mysql_users_add(users, &key, passwd)) + ret = 1; + } + + free(key.user); + + return ret; +} + /** * Load the user/passwd form mysql.user table into the service users' hashtable * environment. @@ -159,7 +247,7 @@ struct users *newusers, *oldusers; * @return -1 on any error or the number of users inserted (0 means no users at all) */ static int -getUsers(SERVICE *service, struct users *users) +getUsers(SERVICE *service, USERS *users) { MYSQL *con = NULL; MYSQL_ROW row; @@ -175,8 +263,6 @@ getUsers(SERVICE *service, struct users *users) char *users_data = NULL; int nusers = 0; int users_data_row_len = MYSQL_USER_MAXLEN + MYSQL_HOST_MAXLEN + MYSQL_PASSWORD_LEN; - struct sockaddr_in serv_addr; - MYSQL_USER_HOST key; /* enable_root for MySQL protocol module means load the root user credentials from backend databases */ if(service->enable_root) { @@ -313,97 +399,26 @@ getUsers(SERVICE *service, struct users *users) * added to hashtable. */ - char ret_ip[INET_ADDRSTRLEN + 1]=""; - const char *rc; - int found_range=0; - int found_any=0; + int rc = 0; - /* prepare the user@host data struct */ - memset(&serv_addr, 0, sizeof(serv_addr)); - memset(&key, 0, sizeof(key)); + rc = add_mysql_users_with_host_ipv4(users, row[0], row[1], strlen(row[2]) ? row[2]+1 : row[2]); - /* set user */ - key.user = strdup(row[0]); - - if(key.user == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [getUsers()] strdup() failed for user %s", + if (rc == 1) { + LOGIF(LD, (skygw_log_write_flush( + LOGFILE_DEBUG, + "%lu [mysql_users_add()] Added user %s@%s", pthread_self(), - row[0]))); + row[0], + row[1]))); - continue; - } + /* Append data in the memory area for SHA1 digest */ + strncat(users_data, row[3], users_data_row_len); - /* handle ANY, Class C,B,A */ - - /* if host == '%', 0 serv_addrkeeps its 0 */ - if (strcmp(row[1], "%") == 0) { - strcpy(ret_ip, "0.0.0.0"); - found_any = 1; + total_users++; } else { - char *tmp; - strcpy(ret_ip, row[1]); - tmp = ret_ip+strlen(ret_ip)-1; - - while(*tmp) { - if (*tmp == '%') { - /* set last byte only to 1 - * avoiding setipadress failure - * for Class C address - */ - found_range++; - if (found_range == 1) - *tmp = '1'; - else - *tmp = '0'; - } - tmp--; - } - } - - if (setipaddress(&serv_addr.sin_addr, ret_ip)) { - - memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr)); - - if (found_range) { - /* let's zero the last IP byte: a.b.c.0 we set above to 1*/ - key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; - } - - rc = inet_ntop(AF_INET, &(key.ipv4).sin_addr, ret_ip, INET_ADDRSTRLEN); - - /* add user@host as key and passwd as value in the MySQL users hash table */ - if (mysql_users_add(users, &key, strlen(row[2]) ? row[2]+1 : row[2])) { - LOGIF(LD, (skygw_log_write_flush( - LOGFILE_DEBUG, - "%lu [mysql_users_add()] Added user %s@%s(%s)", - pthread_self(), - row[0], - row[1], - rc == NULL ? "NULL" : ret_ip))); - - /* Append data in the memory area for SHA1 digest */ - strncat(users_data, row[3], users_data_row_len); - - total_users++; - } else { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [mysql_users_add()] Failed adding user %s@%s(%s)", - pthread_self(), - row[0], - row[1], - rc == NULL ? "NULL" : ret_ip))); - } - - free(key.user); - - } else { - /* setipaddress() failed, skip user add and log this*/ LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, - "%lu [getUsers()] setipaddress failed: user %s@%s not added", + "%lu [mysql_users_add()] Failed adding user %s@%s", pthread_self(), row[0], row[1]))); @@ -511,7 +526,7 @@ static int uh_hfun( void* key) { * Currently only IPv4 addresses are supported * * @param key1 The key value, i.e. username@host (IPv4) - * @param key1 The key value, i.e. username@host (IPv4) + * @param key2 The key value, i.e. username@host (IPv4) * @return The compare value */ @@ -522,7 +537,7 @@ static int uh_cmpfun( void* v1, void* v2) { if (v1 == NULL || v2 == NULL || hu1 == NULL || hu2 == NULL || hu1->user == NULL || hu2->user == NULL) return 0; - if (strcmp(hu1->user, hu2->user) == 0 && (hu1->ipv4.sin_addr.s_addr == hu2->ipv4.sin_addr.s_addr)) { + if (strcmp(hu1->user, hu2->user) == 0 && (hu1->ipv4.sin_addr.s_addr == hu2->ipv4.sin_addr.s_addr) && (hu1->netmask >= hu2->netmask)) { return 0; } else { return 1; @@ -549,6 +564,7 @@ static void *uh_keydup(void* key) { return NULL; memcpy(&rval->ipv4, ¤t_key->ipv4, sizeof(struct sockaddr_in)); + memcpy(&rval->netmask, ¤t_key->netmask, sizeof(int)); return (void *) rval; } @@ -597,19 +613,25 @@ char *mysql_format_user_entry(void *data) if (mysql_user == NULL) return NULL; - if (entry->ipv4.sin_addr.s_addr == INADDR_ANY) { - snprintf(mysql_user, mysql_user_len, "%s@%%", entry->user); - } else if ( (entry->ipv4.sin_addr.s_addr & 0xFF000000) == 0) { - snprintf(mysql_user, mysql_user_len, "%s@%i.%i.%i.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256), (entry->ipv4.sin_addr.s_addr & 0x00FF0000) / (256 * 256)); - } else if ( (entry->ipv4.sin_addr.s_addr & 0xFFFF0000) == 0) { - snprintf(mysql_user, mysql_user_len, "%s@%i.%i.%%.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256)); - } else if ( (entry->ipv4.sin_addr.s_addr & 0xFFFFFF00) == 0) { - snprintf(mysql_user, mysql_user_len, "%s@%i.%%.%%.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF); - } else { + if (entry->ipv4.sin_addr.s_addr == INADDR_ANY && entry->netmask == 0) { + snprintf(mysql_user, mysql_user_len-1, "%s@%%", entry->user); + } else if ( (entry->ipv4.sin_addr.s_addr & 0xFF000000) == 0 && entry->netmask == 24) { + snprintf(mysql_user, mysql_user_len-1, "%s@%i.%i.%i.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256), (entry->ipv4.sin_addr.s_addr & 0x00FF0000) / (256 * 256)); + } else if ( (entry->ipv4.sin_addr.s_addr & 0xFFFF0000) == 0 && entry->netmask == 16) { + snprintf(mysql_user, mysql_user_len-1, "%s@%i.%i.%%.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256)); + } else if ( (entry->ipv4.sin_addr.s_addr & 0xFFFFFF00) == 0 && entry->netmask == 8) { + snprintf(mysql_user, mysql_user_len-1, "%s@%i.%%.%%.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF); + } else if (entry->netmask == 32) { strncpy(mysql_user, entry->user, MYSQL_USER_MAXLEN); strcat(mysql_user, "@"); inet_ntop(AF_INET, &(entry->ipv4).sin_addr, mysql_user+strlen(mysql_user), INET_ADDRSTRLEN); + } else { + snprintf(mysql_user, MYSQL_USER_MAXLEN-6, "warn: %s", entry->user); + strcat(mysql_user, "@"); + inet_ntop(AF_INET, &(entry->ipv4).sin_addr, mysql_user+strlen(mysql_user), INET_ADDRSTRLEN); + } return mysql_user; } + diff --git a/server/core/test/CMakeLists.txt b/server/core/test/CMakeLists.txt index 914fe277e..fcbd343e2 100644 --- a/server/core/test/CMakeLists.txt +++ b/server/core/test/CMakeLists.txt @@ -1,11 +1,14 @@ +add_executable(test_mysql_users test_mysql_users.c) add_executable(test_hash testhash.c) add_executable(test_spinlock testspinlock.c) add_executable(test_filter testfilter.c) add_executable(test_adminusers testadminusers.c) +target_link_libraries(test_mysql_users fullcore MySQLClient) target_link_libraries(test_hash fullcore) target_link_libraries(test_spinlock fullcore) target_link_libraries(test_filter fullcore) target_link_libraries(test_adminusers fullcore) +add_test(testMySQLUsers test_mysql_users) add_test(TestHash test_hash) add_test(TestSpinlock test_spinlock) add_test(TestFilter test_filter) diff --git a/server/core/test/makefile.mysql_users b/server/core/test/makefile.mysql_users deleted file mode 100644 index 074188555..000000000 --- a/server/core/test/makefile.mysql_users +++ /dev/null @@ -1,32 +0,0 @@ -# cleantests - clean local and subdirectories' tests -# buildtests - build all local and subdirectories' tests -# runtests - run all local tests -# testall - clean, build and run local and subdirectories' tests - -include ../../../build_gateway.inc -include ../../../makefile.inc - -CC=cc -DEBUG=Y -cleantests: - - $(DEL) *.o - - $(DEL) test_mysql_users - - $(DEL) *~ - -testall: cleantests buildtests runtests - -buildtests : - $(CC) $(CFLAGS) \ - -I$(ROOT_PATH)/server/include \ - -I$(ROOT_PATH)/utils \ - -I$(ROOT_PATH)/log_manager \ - test_mysql_users.c ../secrets.o ../service.o ../gwbitmask.o ../load_utils.o ../session.o ../poll.o ../dcb.o ../utils.o ../buffer.o ../gw_utils.o ../hashtable.o ../atomic.o ../spinlock.o ../users.o ../dbusers.o ../../../utils/skygw_utils.o ../../../log_manager/log_manager.o -o test_mysql_users -L$(EMBEDDED_LIB) -lmysqlclient -lpthread -lssl -lz -lm -lcrypt -lcrypto -ldl -laio -lrt -lstdc++ -runtests: - @echo "" - @echo "-------------------------------" - @echo $(shell date) - @echo "Test MaxScale core" - @echo "-------------------------------" - @echo "" - @echo "MaxSclale Load MySQL users" - @./test_mysql_users diff --git a/server/core/test/test_mysql_users.c b/server/core/test/test_mysql_users.c index 7dc789d83..a0b806623 100644 --- a/server/core/test/test_mysql_users.c +++ b/server/core/test/test_mysql_users.c @@ -24,6 +24,7 @@ * 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 */ @@ -153,6 +154,62 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor return 0; } +int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *password, char *from) { + USERS *mysql_users; + int ret; + struct sockaddr_in client_addr; + DCB *dcb; + SERVICE *service; + + dcb = dcb_alloc(DCB_ROLE_INTERNAL); + + if (dcb == NULL) { + fprintf(stderr, "dcb_alloc() failed\n"); + return 1; + } + if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL) { + fprintf(stderr, "service_alloc() failed\n"); + return 1; + } + + 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); + return 1; + } + } + + /* 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->users = mysql_users; + + + // the routine returns 1 on success + ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password); + if (!ret) { + fprintf(stderr, "add_mysql_users_with_host_ipv4 passed(%s@%s, %s) FAILED\n", username, hostname, password); + return 1; + } else { + char db_passwd[100]=""; + + dcb->remote=strdup(from); + //fprintf(stderr, "add_mysql_users_with_host_ipv4 passed(%s@%s, %s) OK\n", username, hostname, password); + + fprintf(stderr, "Checking '%s' @ '%s' against (%s@%s)\n", username, from, username, hostname); + + // returns 0 on success + ret = gw_find_mysql_user_password_sha1(username, db_passwd, dcb); + } + + return ret; +} int main() { int ret; @@ -166,6 +223,7 @@ int main() { 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"); @@ -193,15 +251,72 @@ int main() { 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"); + if (ret) fprintf(stderr, "\t-- Expecting no match\n"); + assert(ret == 1); + + ret = set_and_get_mysql_users_wildcards("pippo", "%", "", "127.0.0.1"); + 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"); + if (!ret) fprintf(stderr, "\t-- Expecting ok\n"); + assert(ret == 0); + + ret = set_and_get_mysql_users_wildcards("pippo", "192.168.1.%", "foo", "192.168.2.2"); + 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"); + 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"); + 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"); + if (!ret) fprintf(stderr, "\t-- Expecting ok\n"); + assert(ret == 0); + + ret = set_and_get_mysql_users_wildcards("pippo", "192.0.%.%", "foo", "192.2.0.2"); + 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"); + 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"); + 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"); + 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"); + if (ret) fprintf(stderr, "\t-- Expecting no match\n"); + assert(ret == 1); + + ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.3.2.1"); + if (!ret) fprintf(stderr, "\t-- Expecting ok\n"); + assert(ret == 0); + + ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.%", "foo", "192.134.0.2"); + if (ret) fprintf(stderr, "\t-- Expecting no match\n"); + assert(ret == 1); + fprintf(stderr, "----------------\n"); fprintf(stderr, "<<< Test completed\n"); time(&t); fprintf(stderr, "%s\n", asctime(localtime(&t))); - return ret; + return 0; } diff --git a/server/include/dbusers.h b/server/include/dbusers.h index f9f4a50ab..bcaff05ad 100644 --- a/server/include/dbusers.h +++ b/server/include/dbusers.h @@ -32,6 +32,7 @@ * 25/06/13 Mark Riddoch Initial implementation * 25/02/13 Massimiliano Pinto Added users table refresh rate default values * 28/02/14 Massimiliano Pinto Added MySQL user and host data structure + * 03/10/14 Massimiliano Pinto Added netmask to MySQL user and host data structure * * @endverbatim */ @@ -52,11 +53,13 @@ typedef struct mysql_user_host_key { char *user; struct sockaddr_in ipv4; + int netmask; } MYSQL_USER_HOST; extern int load_mysql_users(SERVICE *service); extern int reload_mysql_users(SERVICE *service); extern int mysql_users_add(USERS *users, MYSQL_USER_HOST *key, char *auth); +extern int add_mysql_users_with_host_ipv4(USERS *users, char *user, char *host, char *passwd); extern USERS *mysql_users_alloc(); extern char *mysql_users_fetch(USERS *users, MYSQL_USER_HOST *key); extern int replace_mysql_users(SERVICE *service); diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index d87cb1a9a..a5281f6fd 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -31,8 +31,9 @@ * localhost entry should be added for the selected user in the backends. * Setting to 1 allow localhost (127.0.0.1 or socket) to match the any host grant via * user@% - * 29/07/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts: + * 29/09/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts: * x.y.z.%, x.y.%.%, x.%.%.% + * 03/10/2014 Massimiliano Pinto Added netmask for wildcard in IPv4 hosts. * */ @@ -1315,7 +1316,7 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le /** * gw_find_mysql_user_password_sha1 * - * The routine fetches look for an user int he MaxScale users' table + * The routine fetches look for an user int the MaxScale users' table * The users' table is dcb->service->users or a different one specified with void *repository * * If found the HEX password, representing sha1(sha1(password)), is converted in binary data and @@ -1339,6 +1340,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, key.user = username; memcpy(&key.ipv4, client, sizeof(struct sockaddr_in)); + key.netmask = 32; LOGIF(LD, (skygw_log_write_flush( @@ -1378,34 +1380,31 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, /* Class C check */ key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; + key.netmask -= 8; user_password = mysql_users_fetch(service->users, &key); if (user_password) { - fprintf(stderr, "+++ Matched Class C for %s\n", dcb->remote); - break; } /* Class B check */ key.ipv4.sin_addr.s_addr &= 0x0000FFFF; + key.netmask -= 8; user_password = mysql_users_fetch(service->users, &key); if (user_password) { - fprintf(stderr, "++ Matched Class B for %s\n", dcb->remote); - break; } /* Class A check */ key.ipv4.sin_addr.s_addr &= 0x000000FF; + key.netmask -= 8; user_password = mysql_users_fetch(service->users, &key); if (user_password) { - fprintf(stderr, "+ Matched Class A for %s\n", dcb->remote); - break; } @@ -1414,6 +1413,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, */ memset(&key.ipv4, 0, sizeof(struct sockaddr_in)); + key.netmask = 0; LOGIF(LD, (skygw_log_write_flush( @@ -1440,8 +1440,6 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, break; } - fprintf(stderr, "%% Matched ANY for %s\n", dcb->remote); - break; } } @@ -1703,11 +1701,9 @@ void protocol_archive_srv_command( s1 = &p->protocol_command; - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [protocol_archive_srv_command] Move command %s from fd %d " - "to command history.", - pthread_self(), + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, + "Move command %s from fd %d to command history.", STRPACKETTYPE(s1->scom_cmd), p->owner_dcb->fd))); @@ -1779,8 +1775,8 @@ void protocol_add_srv_command( p->protocol_command.scom_next = server_command_init(NULL, cmd); } - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, "Added command %s to fd %d.", STRPACKETTYPE(cmd), p->owner_dcb->fd))); @@ -1790,8 +1786,8 @@ void protocol_add_srv_command( while (c != NULL && c->scom_cmd != MYSQL_COM_UNDEFINED) { - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, + LOGIF(LT, (skygw_log_write( + LOGFILE_TRACE, "fd %d : %d %s", p->owner_dcb->fd, c->scom_cmd, From 81b09e7c4de0d8a0d6ec750494210fed467b1de0 Mon Sep 17 00:00:00 2001 From: Mark Riddoch Date: Wed, 8 Oct 2014 11:26:36 +0100 Subject: [PATCH 10/39] Additional tests for maxadmin and diagnostics within maxscale --- client/test/maxadmin_test.sh | 129 +++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 12 deletions(-) diff --git a/client/test/maxadmin_test.sh b/client/test/maxadmin_test.sh index b04312da4..5540fc380 100644 --- a/client/test/maxadmin_test.sh +++ b/client/test/maxadmin_test.sh @@ -19,58 +19,58 @@ else fi maxadmin --password=skysql help >& /dev/null if [ $? -eq "1" ]; then - echo "Auth test (long option): Failed" + echo "Auth test (long option): Failed" failure=`expr $failure + 1` else passed=`expr $passed + 1` - echo "Auth test (long option): Passed" + echo "Auth test (long option): Passed" fi maxadmin -pskysql enable log debug >& /dev/null if [ $? -eq "1" ]; then - echo "Enable debug log: Failed" + echo "Enable debug log: Failed" failure=`expr $failure + 1` else passed=`expr $passed + 1` - echo "Enable debug log: Passed" + echo "Enable debug log: Passed" fi maxadmin -pskysql enable log trace >& /dev/null if [ $? -eq "1" ]; then - echo "Enable trace log: Failed" + echo "Enable trace log: Failed" failure=`expr $failure + 1` else passed=`expr $passed + 1` - echo "Enable trace log: Passed" + echo "Enable trace log: Passed" fi maxadmin -pskysql disable log debug >& /dev/null if [ $? -eq "1" ]; then - echo "Disable debug log: Failed" + echo "Disable debug log: Failed" failure=`expr $failure + 1` else passed=`expr $passed + 1` - echo "Disable debug log: Passed" + echo "Disable debug log: Passed" fi maxadmin -pskysql disable log trace >& /dev/null if [ $? -eq "1" ]; then - echo "Disable trace log: Failed" + echo "Disable trace log: Failed" failure=`expr $failure + 1` else passed=`expr $passed + 1` - echo "Disable trace log: Passed" + echo "Disable trace log: Passed" fi for cmd in clients dcbs filters listeners modules monitors services servers sessions threads do maxadmin -pskysql list $cmd | grep -s '-' >& /dev/null if [ $? -eq "1" ]; then - echo "list command ($cmd): Failed" + echo "list command ($cmd): Failed" failure=`expr $failure + 1` else passed=`expr $passed + 1` - echo "list command ($cmd): Passed" + echo "list command ($cmd): Passed" fi done @@ -206,5 +206,110 @@ do fi done +maxadmin -pskysql list services | \ + awk -F\| '{ if (NF > 1) { sub(/ +$/, "", $1); printf("show service \"%s\"\n", $1); } }' > script1.$$ +grep -cs "show service" script1.$$ >/dev/null +if [ $? -ne "0" ]; then + echo "list services: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "list services: Passed" +fi +maxadmin -pskysql script1.$$ | grep -cs 'Service' > /dev/null +if [ $? -ne "0" ]; then + echo "Show Service: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "Show Service: Passed" +fi +rm -f script1.$$ + + +maxadmin -pskysql list monitors | \ + awk -F\| '{ if (NF > 1) { sub(/ +$/, "", $1); printf("show monitor \"%s\"\n", $1); } }' > script1.$$ +grep -cs "show monitor" script1.$$ >/dev/null +if [ $? -ne "0" ]; then + echo "list monitors: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "list monitors: Passed" +fi +maxadmin -pskysql script1.$$ | grep -cs 'Monitor' > /dev/null +if [ $? -ne "0" ]; then + echo "Show Monitor: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "Show Monitor: Passed" +fi +rm -f script1.$$ + + +maxadmin -pskysql list sessions | \ + awk -F\| ' /^0x/ { if (NF > 1) { sub(/ +$/, "", $1); printf("show session \"%s\"\n", $1); } }' > script1.$$ +grep -cs "show session" script1.$$ >/dev/null +if [ $? -ne "0" ]; then + echo "list sessions: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "list sessions: Passed" +fi +maxadmin -pskysql script1.$$ | grep -cs 'Session' > /dev/null +if [ $? -ne "0" ]; then + echo "Show Session: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "Show Session: Passed" +fi +rm -f script1.$$ + + +maxadmin -pskysql list dcbs | \ + awk -F\| ' /^ 0x/ { if (NF > 1) { sub(/ +$/, "", $1); sub(/ 0x/, "0x", $1); printf("show dcb \"%s\"\n", $1); } }' > script1.$$ +grep -cs "show dcb" script1.$$ >/dev/null +if [ $? -ne "0" ]; then + echo "list dcbs: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "list dcbs: Passed" +fi +maxadmin -pskysql script1.$$ | grep -cs 'DCB' > /dev/null +if [ $? -ne "0" ]; then + echo "Show DCB: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "Show DCB: Passed" +fi +rm -f script1.$$ + + +maxadmin -pskysql list services | \ + awk -F\| '{ if (NF > 1) { sub(/ +$/, "", $1); printf("show dbusers \"%s\"\n", $1); } }' > script1.$$ +grep -cs "show dbusers" script1.$$ >/dev/null +if [ $? -ne "0" ]; then + echo "list services: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "list services: Passed" +fi +maxadmin -pskysql script1.$$ | grep -cs 'Users table data' > /dev/null +if [ $? -ne "0" ]; then + echo "Show dbusers: Failed" + failure=`expr $failure + 1` +else + passed=`expr $passed + 1` + echo "Show dbusers: Passed" +fi +rm -f script1.$$ + + echo "Test run complete. $passed passes, $failure failures" exit $failure From 8cbfb90ce867dd3d2ad0b39145885eb0f9fc0c45 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Oct 2014 10:26:14 +0300 Subject: [PATCH 11/39] Fixed a missing 'else()' from macros.cmake and used unset instead of set when clearing variables. --- macros.cmake | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/macros.cmake b/macros.cmake index cc29a5e09..afb95f47c 100644 --- a/macros.cmake +++ b/macros.cmake @@ -82,24 +82,29 @@ macro(check_dirs) set(DEPS_OK TRUE CACHE BOOL "If all the dependencies were found.") # Find the MySQL headers if they were not defined + if(DEFINED MYSQL_DIR) if(DEBUG_OUTPUT) message(STATUS "Searching for MySQL headers at: ${MYSQL_DIR}") endif() find_path(MYSQL_DIR_LOC mysql.h PATHS ${MYSQL_DIR} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH) + else() + find_path(MYSQL_DIR_LOC mysql.h PATH_SUFFIXES mysql mariadb) endif() - find_path(MYSQL_DIR_LOC mysql.h PATH_SUFFIXES mysql mariadb) + if(DEBUG_OUTPUT) message(STATUS "Search returned: ${MYSQL_DIR_LOC}") endif() - if(${MYSQL_DIR_LOC} STREQUAL "MYSQL_DIR_LOC-NOTFOUND") + + if(${MYSQL_DIR_LOC} MATCHES "NOTFOUND") set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.") message(FATAL_ERROR "Fatal Error: MySQL headers were not found.") else() - message(STATUS "Using MySQL headers found at: ${MYSQL_DIR}") set(MYSQL_DIR ${MYSQL_DIR_LOC} CACHE PATH "Path to MySQL headers" FORCE) + message(STATUS "Using MySQL headers found at: ${MYSQL_DIR}") endif() - set(MYSQL_DIR_LOC "" INTERNAL) + + unset(MYSQL_DIR_LOC) # Find the errmsg.sys file if it was not defied if( DEFINED ERRMSG ) @@ -113,7 +118,7 @@ macro(check_dirs) message(STATUS "Using errmsg.sys found at: ${ERRMSG_FILE}") endif() set(ERRMSG ${ERRMSG_FILE} CACHE FILEPATH "Path to the errmsg.sys file." FORCE) - set(ERRMSG_FILE "" INTERNAL) + unset(ERRMSG_FILE) # Find the embedded mysql library if(STATIC_EMBEDDED) @@ -133,7 +138,7 @@ macro(check_dirs) endif() set(EMBEDDED_LIB ${EMBEDDED_LIB_STATIC} CACHE FILEPATH "Path to libmysqld" FORCE) set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES}) - set(OLD_SUFFIXES "" INTERNAL) + unset(OLD_SUFFIXES) else() if (DEFINED EMBEDDED_LIB) @@ -150,8 +155,8 @@ macro(check_dirs) set(EMBEDDED_LIB ${EMBEDDED_LIB_DYNAMIC} CACHE FILEPATH "Path to libmysqld" FORCE) endif() - set(EMBEDDED_LIB_DYNAMIC "" INTERNAL) - set(EMBEDDED_LIB_STATIC "" INTERNAL) + unset(EMBEDDED_LIB_DYNAMIC) + unset(EMBEDDED_LIB_STATIC) # Inform the user about the embedded library if( (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_STATIC-NOTFOUND") OR (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_DYNAMIC-NOTFOUND")) @@ -176,8 +181,8 @@ macro(check_dirs) else() set(DEB_BASED FALSE CACHE BOOL "If init.d script uses /lib/lsb/init-functions instead of /etc/rc.d/init.d/functions.") endif() - set(DEB_FNC "" INTERNAL) - set(RPM_FNC "" INTERNAL) + unset(DEB_FNC) + unset(RPM_FNC) #Check RabbitMQ headers and libraries if(BUILD_RABBITMQ) From ebb3b52fdb7e43d35564a3a3775754c15e68e895 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Oct 2014 12:30:21 +0300 Subject: [PATCH 12/39] Included the my_config.h header before any system headers if mysql headers were used. --- query_classifier/query_classifier.h | 1 + query_classifier/test/canonical_tests/canonizer.c | 1 + query_classifier/test/classify.c | 1 + server/core/config.c | 1 + server/core/gateway.c | 1 + server/core/poll.c | 1 + server/modules/routing/debugcmd.c | 1 + server/modules/routing/readwritesplit/readwritesplit.c | 1 + 8 files changed, 8 insertions(+) diff --git a/query_classifier/query_classifier.h b/query_classifier/query_classifier.h index db2011642..3600bce5a 100644 --- a/query_classifier/query_classifier.h +++ b/query_classifier/query_classifier.h @@ -18,6 +18,7 @@ Copyright MariaDB Corporation Ab */ /** getpid */ +#include #include #include #include diff --git a/query_classifier/test/canonical_tests/canonizer.c b/query_classifier/test/canonical_tests/canonizer.c index 7e33fe4a1..bffe9c1b9 100644 --- a/query_classifier/test/canonical_tests/canonizer.c +++ b/query_classifier/test/canonical_tests/canonizer.c @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/query_classifier/test/classify.c b/query_classifier/test/classify.c index 8eafbdc5c..96a001771 100644 --- a/query_classifier/test/classify.c +++ b/query_classifier/test/classify.c @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/server/core/config.c b/server/core/config.c index ead016000..61bc6157d 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -41,6 +41,7 @@ * * @endverbatim */ +#include #include #include #include diff --git a/server/core/gateway.c b/server/core/gateway.c index 2749850fe..34783bc52 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -40,6 +40,7 @@ * @endverbatim */ #define _XOPEN_SOURCE 700 +#include #include #include #include diff --git a/server/core/poll.c b/server/core/poll.c index e1a3f80ec..bfb1e65c6 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -15,6 +15,7 @@ * * Copyright MariaDB Corporation Ab 2013-2014 */ +#include #include #include #include diff --git a/server/modules/routing/debugcmd.c b/server/modules/routing/debugcmd.c index 8f51d531a..65384bfc6 100644 --- a/server/modules/routing/debugcmd.c +++ b/server/modules/routing/debugcmd.c @@ -44,6 +44,7 @@ * * @endverbatim */ +#include #include #include #include diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 8d5f51727..505c7c5d1 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -15,6 +15,7 @@ * * Copyright MariaDB Corporation Ab 2013-2014 */ +#include #include #include #include From e00dbb9beb58a322dc6e25b70bef74676a802fd7 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Oct 2014 13:17:12 +0300 Subject: [PATCH 13/39] Added missing my_config.h header to mqfilter.c --- server/modules/filter/mqfilter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/modules/filter/mqfilter.c b/server/modules/filter/mqfilter.c index e6a6c12b1..ed0096bbf 100644 --- a/server/modules/filter/mqfilter.c +++ b/server/modules/filter/mqfilter.c @@ -58,6 +58,7 @@ *@endverbatim * See the individual struct documentations for logging trigger parameters */ +#include #include #include #include From cd1bea82e87e6b325bf21d8c4f45c9dc15b49a07 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Oct 2014 14:46:11 +0300 Subject: [PATCH 14/39] Updated macros.cmake with different string matching parameters on searched libraries. --- macros.cmake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/macros.cmake b/macros.cmake index afb95f47c..bc1bd24e6 100644 --- a/macros.cmake +++ b/macros.cmake @@ -189,9 +189,10 @@ macro(check_dirs) if(DEFINED RABBITMQ_LIB) find_library(RMQ_LIB rabbitmq PATHS ${RABBITMQ_LIB} NO_DEFAULT_PATH) + else() + find_library(RMQ_LIB rabbitmq) endif() - find_library(RMQ_LIB rabbitmq) - if(RMQ_LIB STREQUAL "RMQ_LIB-NOTFOUND") + if(RMQ_LIB MATCHES "NOTFOUND") set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.") message(FATAL_ERROR "Cannot find RabbitMQ libraries, please define the path to the libraries with -DRABBITMQ_LIB=") else() @@ -201,9 +202,10 @@ macro(check_dirs) if(DEFINED RABBITMQ_HEADERS) find_file(RMQ_HEADERS amqp.h PATHS ${RABBITMQ_HEADERS} NO_DEFAULT_PATH) + else() + find_file(RMQ_HEADERS amqp.h) endif() - find_file(RMQ_HEADERS amqp.h) - if(RMQ_HEADERS STREQUAL "RMQ_HEADERS-NOTFOUND") + if(RMQ_HEADERS MATCHES "NOTFOUND") set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.") message(FATAL_ERROR "Cannot find RabbitMQ headers, please define the path to the headers with -DRABBITMQ_HEADERS=") else() From be08f22ae1bb0c19f8d526d2a6a9234b8d20b37c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Oct 2014 16:38:54 +0300 Subject: [PATCH 15/39] Changed old references to SkySQL to MariaDB Corporation and Gateway to MaxScale. --- query_classifier/test/classify.c | 2 +- server/core/buffer.c | 6 +++--- server/modules/filter/test/harness.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/query_classifier/test/classify.c b/query_classifier/test/classify.c index 96a001771..4fe33a68b 100644 --- a/query_classifier/test/classify.c +++ b/query_classifier/test/classify.c @@ -9,7 +9,7 @@ #include static char* server_options[] = { - "SkySQL Gateway", + "MariaDB Corporation MaxScale", "--no-defaults", "--datadir=.", "--language=.", diff --git a/server/core/buffer.c b/server/core/buffer.c index 46315cf69..9ee13c87f 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -1,5 +1,5 @@ /* - * This file is distributed as part of the SkySQL Gateway. It is free + * This file is distributed as part of the MariaDB Corporation MaxScale. It is free * software: you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation, * version 2. @@ -13,11 +13,11 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2013 + * Copyright MariaDB Corporation Ab 2014 */ /** - * @file buffer.h - The Gateway buffer management functions + * @file buffer.h - The MaxScale buffer management functions * * The buffer management is based on the principle of a linked list * of variable size buffer, the intention beign to allow longer diff --git a/server/modules/filter/test/harness.h b/server/modules/filter/test/harness.h index 69b12b9d9..c30c266c2 100644 --- a/server/modules/filter/test/harness.h +++ b/server/modules/filter/test/harness.h @@ -1,7 +1,7 @@ #ifndef _FILTER_HARNESS_H #define _FILTER_HARNESS_H /* - * This file is distributed as part of the SkySQL Gateway. It is free + * This file is distributed as part of the MariaDB Corporation MaxScale. It is free * software: you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation, * version 2. @@ -15,7 +15,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2013 + * Copyright MariaDB Corporation Ab 2014 */ /** From 7165f5d29b73394576abb538ba170246a86ba553 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Oct 2014 17:14:49 +0300 Subject: [PATCH 16/39] Added more checks for RabbitMQ library versions. --- macros.cmake | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/macros.cmake b/macros.cmake index bc1bd24e6..920c915c7 100644 --- a/macros.cmake +++ b/macros.cmake @@ -57,11 +57,12 @@ endmacro() macro(check_deps) + # Check for libraries MaxScale depends on set(MAXSCALE_DEPS aio ssl crypt crypto z m dl rt pthread) foreach(lib ${MAXSCALE_DEPS}) find_library(lib${lib} ${lib}) - if((DEFINED lib${lib}) AND (${lib${lib}} STREQUAL "lib${lib}-NOTFOUND")) + if((DEFINED lib${lib}) AND (${lib${lib}} MATCHES "NOTFOUND")) set(DEPS_ERROR TRUE) set(FAILED_DEPS "${FAILED_DEPS} lib${lib}") elseif(DEBUG_OUTPUT) @@ -159,7 +160,7 @@ macro(check_dirs) unset(EMBEDDED_LIB_STATIC) # Inform the user about the embedded library - if( (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_STATIC-NOTFOUND") OR (${EMBEDDED_LIB} STREQUAL "EMBEDDED_LIB_DYNAMIC-NOTFOUND")) + if( (${EMBEDDED_LIB} MATCHES "NOTFOUND") OR (${EMBEDDED_LIB} MATCHES "NOTFOUND")) set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.") message(FATAL_ERROR "Library not found: libmysqld. If your install of MySQL is in a non-default location, please provide the location with -DEMBEDDED_LIB=") else() @@ -186,6 +187,7 @@ macro(check_dirs) #Check RabbitMQ headers and libraries if(BUILD_RABBITMQ) + include(CheckCSourceCompiles) if(DEFINED RABBITMQ_LIB) find_library(RMQ_LIB rabbitmq PATHS ${RABBITMQ_LIB} NO_DEFAULT_PATH) @@ -212,7 +214,12 @@ macro(check_dirs) set(RABBITMQ_HEADERS ${RMQ_HEADERS} CACHE PATH "Path to RabbitMQ headers" FORCE) message(STATUS "Using RabbitMQ headers found at: ${RABBITMQ_HEADERS}") endif() - + set(CMAKE_REQUIRED_INCLUDES ${RABBITMQ_HEADERS}) + check_c_source_compiles("#include \n int main(){if(AMQP_DELIVERY_PERSISTENT){return 0;}return 1;}" HAVE_RMQ50) + if(NOT HAVE_RMQ50) + message(FATAL_ERROR "Old version of RabbitMQ-C library found. Version 0.5 or newer is required.") + endif() + endif() endmacro() From 34400ee551b0c1e15c029342724a20acd8e9375e Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Fri, 10 Oct 2014 23:53:55 +0300 Subject: [PATCH 17/39] Fixed the use of nanosleep which removed a spinloop and degraded the performance dramatically. --- server/core/gateway.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server/core/gateway.c b/server/core/gateway.c index 34783bc52..8e6dbb5ee 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -1671,9 +1671,11 @@ static void log_flush_cb( void* arg) { ssize_t timeout_ms = *(ssize_t *)arg; - const struct timespec ts1 = {0, 1000000*timeout_ms}; - struct timespec ts2; + struct timespec ts1; + ts1.tv_sec = timeout_ms/1000; + ts1.tv_nsec = (timeout_ms%1000)*1000000; + LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "Started MaxScale log flusher."))); while (!do_exit) { @@ -1681,7 +1683,7 @@ static void log_flush_cb( skygw_log_flush(LOGFILE_MESSAGE); skygw_log_flush(LOGFILE_TRACE); skygw_log_flush(LOGFILE_DEBUG); - nanosleep(&ts1, &ts2); + nanosleep(&ts1, NULL); } LOGIF(LM, (skygw_log_write(LOGFILE_MESSAGE, "Finished MaxScale log flusher."))); From 7117eae2b29046ca4a5f67052a0776b9d9ca2ff2 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 13 Oct 2014 12:12:40 +0300 Subject: [PATCH 18/39] CMake will now properly create the log folder when installing. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab5509402..54c447894 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,7 +98,7 @@ message(STATUS "Installing MaxScale to: ${CMAKE_INSTALL_PREFIX}/") install(FILES server/MaxScale_template.cnf DESTINATION etc) install(FILES ${ERRMSG} DESTINATION mysql) install(FILES ${DOCS} DESTINATION Documentation) - +install(DIRECTORY DESTINATION log) # See if we are on a RPM-capable or DEB-capable system find_program(RPMBUILD rpmbuild) find_program(DEBBUILD dpkg-buildpackage) From d335794715b21f9a8a692e73cdb74fc36fc5b0da Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 13 Oct 2014 13:57:08 +0300 Subject: [PATCH 19/39] Added a 'buildtests' target that only builds the test version. --- CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54c447894..e6fbec0d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,10 +136,15 @@ set(CPACK_RPM_USER_FILELIST "%ignore /etc/init.d") set(CPACK_RPM_USER_FILELIST "%ignore /etc/ld.so.conf.d") set(CPACK_RPM_USER_FILELIST "%ignore /etc") include(CPack) +add_custom_target(buildtests + COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DBUILD_TYPE=Debug -DINSTALL_DIR=${CMAKE_BINARY_DIR} -DINSTALL_SYSTEM_FILES=N ${CMAKE_SOURCE_DIR} + COMMAND make + COMMENT "Building test suite..." VERBATIM +) add_custom_target(testall COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DBUILD_TYPE=Debug -DINSTALL_DIR=${CMAKE_BINARY_DIR} -DINSTALL_SYSTEM_FILES=N ${CMAKE_SOURCE_DIR} COMMAND make install COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null" COMMAND /bin/sh -c "make test || echo \"Test results written to: ${CMAKE_BINARY_DIR}/Testing/Temporary/\"" COMMAND killall maxscale - COMMENT "Running full test suite" VERBATIM) \ No newline at end of file + COMMENT "Running full test suite..." VERBATIM) \ No newline at end of file From 0fc47efec3be03674c05f85230c77ec66608a856 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 14 Oct 2014 12:42:40 +0300 Subject: [PATCH 20/39] Added a debugging function that outputs debugging messages if DEBUG_OUTPUT=Y --- macros.cmake | 63 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/macros.cmake b/macros.cmake index 920c915c7..ce5a21ef9 100644 --- a/macros.cmake +++ b/macros.cmake @@ -1,9 +1,15 @@ +function(debugmsg MSG) + if(DEBUG_OUTPUT) + message(STATUS "DEBUG: ${MSG}") + endif() +endfunction() + macro(set_maxscale_version) #MaxScale version number set(MAXSCALE_VERSION_MAJOR "1") set(MAXSCALE_VERSION_MINOR "0") - set(MAXSCALE_VERSION_PATCH "1") + set(MAXSCALE_VERSION_PATCH "2") set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}") set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}-beta") @@ -85,17 +91,13 @@ macro(check_dirs) # Find the MySQL headers if they were not defined if(DEFINED MYSQL_DIR) - if(DEBUG_OUTPUT) - message(STATUS "Searching for MySQL headers at: ${MYSQL_DIR}") - endif() + debugmsg("Searching for MySQL headers at: ${MYSQL_DIR}") find_path(MYSQL_DIR_LOC mysql.h PATHS ${MYSQL_DIR} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH) else() find_path(MYSQL_DIR_LOC mysql.h PATH_SUFFIXES mysql mariadb) endif() - - if(DEBUG_OUTPUT) - message(STATUS "Search returned: ${MYSQL_DIR_LOC}") - endif() + +debugmsg("Search returned: ${MYSQL_DIR_LOC}") if(${MYSQL_DIR_LOC} MATCHES "NOTFOUND") set(DEPS_OK FALSE CACHE BOOL "If all the dependencies were found.") @@ -109,6 +111,7 @@ macro(check_dirs) # Find the errmsg.sys file if it was not defied if( DEFINED ERRMSG ) + debugmsg("Looking for errmsg.sys at: ${ERRMSG}") find_file(ERRMSG_FILE errmsg.sys PATHS ${ERRMSG} NO_DEFAULT_PATH) endif() find_file(ERRMSG_FILE errmsg.sys PATHS /usr/share/mysql /usr/local/share/mysql PATH_SUFFIXES english) @@ -122,42 +125,52 @@ macro(check_dirs) unset(ERRMSG_FILE) # Find the embedded mysql library - if(STATIC_EMBEDDED) + + if (DEFINED EMBEDDED_LIB) + debugmsg("Searching for the embedded library at: ${EMBEDDED_LIB}") + if(${CMAKE_VERSION} VERSION_LESS 2.12 ) + set(COMP_VAR PATH) + else() + set(COMP_VAR DIRECTORY) + endif() + get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} ${COMP_VAR}) + endif() + if(STATIC_EMBEDDED) + + debugmsg("Using the static embedded library...") set(OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") if (DEFINED EMBEDDED_LIB) - if(DEBUG_OUTPUT) - message(STATUS "Searching for libmysqld.a at: ${EMBEDDED_LIB}") - endif() + debugmsg("Searching for libmysqld.a at: ${EMBEDDED_LIB}") find_library(EMBEDDED_LIB_STATIC libmysqld.a PATHS ${EMBEDDED_LIB} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH) else() find_library(EMBEDDED_LIB_STATIC libmysqld.a PATH_SUFFIXES mysql mariadb) endif() - if(DEBUG_OUTPUT) - message(STATUS "Search returned: ${EMBEDDED_LIB_STATIC}") - endif() + debugmsg("Search returned: ${EMBEDDED_LIB_STATIC}") + set(EMBEDDED_LIB ${EMBEDDED_LIB_STATIC} CACHE FILEPATH "Path to libmysqld" FORCE) set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES}) - unset(OLD_SUFFIXES) - else() + else() + debugmsg("Using the dynamic embedded library...") + set(OLD_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".so") if (DEFINED EMBEDDED_LIB) - if(DEBUG_OUTPUT) - message(STATUS "Searching for libmysqld.so at: ${EMBEDDED_LIB}") - endif() + debugmsg("Searching for libmysqld.so at: ${EMBEDDED_LIB}") find_library(EMBEDDED_LIB_DYNAMIC mysqld PATHS ${EMBEDDED_LIB} PATH_SUFFIXES mysql mariadb NO_DEFAULT_PATH) else() find_library(EMBEDDED_LIB_DYNAMIC mysqld PATH_SUFFIXES mysql mariadb) endif() - if(DEBUG_OUTPUT) - message(STATUS "Search returned: ${EMBEDDED_LIB_DYNAMIC}") - endif() + debugmsg("Search returned: ${EMBEDDED_LIB_DYNAMIC}") set(EMBEDDED_LIB ${EMBEDDED_LIB_DYNAMIC} CACHE FILEPATH "Path to libmysqld" FORCE) - + set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_SUFFIXES}) + endif() + unset(EMBEDDED_LIB_DYNAMIC) unset(EMBEDDED_LIB_STATIC) + unset(OLD_SUFFIXES) # Inform the user about the embedded library if( (${EMBEDDED_LIB} MATCHES "NOTFOUND") OR (${EMBEDDED_LIB} MATCHES "NOTFOUND")) @@ -238,4 +251,4 @@ endif() endforeach() list(REMOVE_DUPLICATES ALLDIRS) set(${VAR} "${ALLDIRS}" CACHE PATH " " FORCE) -endfunction() \ No newline at end of file +endfunction() From 726ab87f4b050ae587bec863b92a0ec2ca886a6d Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Tue, 14 Oct 2014 13:22:16 +0300 Subject: [PATCH 21/39] Fix to #575, http://bugs.mariadb.com/show_bug.cgi?id=575 log_manager.cc: Log manager handles cases where there are mismatch in user privileges. Mark log files enabled in the global lm_enabled_logfiles_bitmask after initialization so that it reflects reality in error cases. In general, take into account the possibility that any phase in initialization may fail and read return values. Replaced file_exists_and_is_writable to check_file_and_path which has a slightly different logic and which detects if file open fails for a few different reasons. Improved logging (in stderr) in general in error cases. gateway.c: Also check home directory accessibility in case when it is provided as a command-line argument. Added function check_dir_access to provide that function. Read return value of skysql_logmanager_init and exit (nicely) if it failed. skygw_utils.cc: initialize mlist with version number 2, which indicates that object is initialized (different than zero) and that there are no active updates on the object (version%2==0). --- log_manager/log_manager.cc | 297 +++++++++++++++++++++++-------------- server/core/gateway.c | 188 +++++++++++++++-------- utils/skygw_utils.cc | 2 + utils/skygw_utils.h | 2 - 4 files changed, 317 insertions(+), 172 deletions(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index 59e108920..f9aeb57d3 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -270,12 +270,14 @@ static void blockbuf_register(blockbuf_t* bb); static void blockbuf_unregister(blockbuf_t* bb); static bool logfile_set_enabled(logfile_id_t id, bool val); static char* add_slash(char* str); -static bool file_exists_and_is_writable(char* filename, bool* writable); + +static bool check_file_and_path( + char* filename, + bool* nameconflict, + bool* writable); + static bool file_is_symlink(char* filename); - - - const char* get_suffix_default(void) { return ".log"; @@ -356,11 +358,6 @@ static bool logmanager_init_nomutex( fw = &lm->lm_filewriter; fn->fn_state = UNINIT; fw->fwr_state = UNINIT; - - /** - * Set global variable - */ - lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; /** Initialize configuration including log file naming info */ if (!fnames_conf_init(fn, argc, argv)) { @@ -368,14 +365,23 @@ static bool logmanager_init_nomutex( } /** Initialize logfiles */ - if(!logfiles_init(lm)) { - goto return_succp; + if(!logfiles_init(lm)) + { + err = 1; + goto return_succp; } - /** Initialize filewriter data and open the (first) log file(s) + /** + * Set global variable + */ + lm_enabled_logfiles_bitmask = lm->lm_enabled_logfiles; + + /** Initialize filewriter data and open the (first) log file(s) * for each log file type. */ - if (!filewriter_init(lm, fw, lm->lm_clientmes, lm->lm_logmes)) { - goto return_succp; + if (!filewriter_init(lm, fw, lm->lm_clientmes, lm->lm_logmes)) + { + err = 1; + goto return_succp; } /** Initialize and start filewriter thread */ @@ -383,8 +389,9 @@ static bool logmanager_init_nomutex( thr_filewriter_fun, (void *)fw); - if ((err = skygw_thread_start(fw->fwr_thread)) != 0) { - goto return_succp; + if ((err = skygw_thread_start(fw->fwr_thread)) != 0) + { + goto return_succp; } /** Wait message from filewriter_thr */ skygw_message_wait(fw->fwr_clientmes); @@ -393,10 +400,11 @@ static bool logmanager_init_nomutex( lm->lm_enabled = true; return_succp: - if (err != 0) { + if (err != 0) + { /** This releases memory of all created objects */ logmanager_done_nomutex(); - fprintf(stderr, "* Initializing logmanager failed.\n"); + fprintf(stderr, "*\n* Error : Initializing log manager failed.\n*\n"); } return succp; } @@ -1769,7 +1777,7 @@ static bool logfiles_init( write_syslog); if (!succp) { - fprintf(stderr, "Initializing logfiles failed\n"); + fprintf(stderr, "*\n* Error : Initializing log files failed.\n"); break; } lid <<= 1; @@ -1917,10 +1925,11 @@ static char* add_slash( return str; } -/** - * @node Check if the file exists in the local file system and if it does, - * whether it is writable. - * + +/** + * @node Check if the path and file exist in the local file system and if they do, + * check if they are accessible and writable. + * * Parameters: * @param filename - * @@ -1928,55 +1937,91 @@ static char* add_slash( * @param writable - * * - * @return + * @return true & writable if file exists and it is writable, + * true & not writable if file exists but it can't be written, + * false & writable if file doesn't exist but directory could be written, and + * false & not writable if directory can't be written. * - * - * @details Note, that an space character is written to the end of file. + * @details Note, that a space character is written to the end of file. * TODO: recall what was the reason for not succeeding with simply * calling access, and fstat. vraa 26.11.13 - * */ -static bool file_exists_and_is_writable( - char* filename, - bool* writable) +static bool check_file_and_path( + char* filename, + bool* writable) { - int fd; - bool exists = true; - - if (filename == NULL) - { - exists = false; - } - else - { - fd = open(filename, O_CREAT|O_EXCL, S_IRWXU); - - /** file exist */ - if (fd == -1) - { - /** Open file and write a byte for test */ - fd = open(filename, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG); - - if (fd != -1) - { - char c = ' '; - if (write(fd, &c, 1) == 1) - { - *writable = true; - } - close(fd); - } - } - else - { - close(fd); - unlink(filename); - exists = false; - } - } - return exists; + int fd; + bool exists; + + if (filename == NULL) + { + exists = false; + *writable = false; + } + else + { + fd = open(filename, O_CREAT|O_EXCL, S_IRWXU); + + if (fd == -1) + { + /** File exists, check permission to read/write */ + if (errno == EEXIST) + { + /** Open file and write a byte for test */ + fd = open(filename, O_CREAT|O_RDWR, S_IRWXU|S_IRWXG); + + if (fd == -1) + { + fprintf(stderr, + "*\n* Error : Can't access %s due " + "to %s.\n", + filename, + strerror(errno)); + *writable = false; + } + else + { + char c = ' '; + if (write(fd, &c, 1) == 1) + { + *writable = true; + } + else + { + fprintf(stderr, + "*\n* Error : Can't write to " + "%s due to %s.\n", + filename, + strerror(errno)); + *writable = false; + } + close(fd); + } + exists = true; + } + else + { + fprintf(stderr, + "*\n* Error : Can't access %s due to %s.\n", + filename, + strerror(errno)); + exists = false; + *writable = false; + } + } + else + { + close(fd); + unlink(filename); + exists = false; + *writable = true; + } + } + return exists; } + + static bool file_is_symlink( char* filename) { @@ -2112,7 +2157,8 @@ static bool logfile_init( logfile->lf_full_file_name = form_full_file_name(strparts, logfile->lf_name_seqno, 2); - if (store_shmem) { + if (store_shmem) + { strparts[0].sp_string = logfile->lf_linkpath; /** * Create name for link file @@ -2121,17 +2167,7 @@ static bool logfile_init( form_full_file_name(strparts, logfile->lf_name_seqno, 2); - fprintf(stderr, "%s\t: %s->%s\n", - STRLOGNAME(logfile_id), - logfile->lf_full_link_name, - logfile->lf_full_file_name); } - else - { - fprintf(stderr, "%s\t: %s\n", - STRLOGNAME(logfile_id), - logfile->lf_full_file_name); - } /** * At least one of the files couldn't be created. Increase * sequence number and retry until succeeds. @@ -2147,32 +2183,57 @@ static bool logfile_init( * If file exists but is different type, create fails and * new, increased sequence number is added to file name. */ - if (file_exists_and_is_writable(logfile->lf_full_file_name, - &writable)) - { - if (!writable || - file_is_symlink(logfile->lf_full_file_name)) - { - nameconflicts = true; - goto file_create_fail; - } - } - - if (store_shmem) - { - writable = false; + if (check_file_and_path( + logfile->lf_full_file_name, + &writable)) + { + /** Found similarly named file which isn't writable */ + if (!writable || + file_is_symlink(logfile->lf_full_file_name)) + { + nameconflicts = true; + goto file_create_fail; + } + } + else + { + /** + * Opening the file failed for some other reason than + * existing non-writable file. Shut down. + */ + if (!writable) + { + succp = false; + goto return_with_succp; + } + } - if (file_exists_and_is_writable( - logfile->lf_full_link_name, - &writable)) - { - if (!writable || - !file_is_symlink(logfile->lf_full_link_name)) - { - nameconflicts = true; - goto file_create_fail; - } - } + if (store_shmem) + { + if (check_file_and_path( + logfile->lf_full_file_name, + &writable)) + { + /** Found similarly named file which isn't writable */ + if (!writable || + file_is_symlink(logfile->lf_full_file_name)) + { + nameconflicts = true; + goto file_create_fail; + } + } + else + { + /** + * Opening the file failed for some other reason than + * existing non-writable file. Shut down. + */ + if (!writable) + { + succp = false; + goto return_with_succp; + } + } } file_create_fail: if (namecreatefail || nameconflicts) @@ -2189,7 +2250,6 @@ file_create_fail: free(logfile->lf_full_link_name); logfile->lf_full_link_name = NULL; } - goto return_with_succp; } } while (namecreatefail || nameconflicts); /** @@ -2203,11 +2263,24 @@ file_create_fail: MAXNBLOCKBUFS) == NULL) { ss_dfprintf(stderr, - "Initializing logfile blockbuf list " - "failed\n"); + "*\n* Error : Initializing buffers for log files " + "failed."); logfile_free_memory(logfile); goto return_with_succp; } + if (store_shmem) + { + fprintf(stderr, "%s\t: %s->%s\n", + STRLOGNAME(logfile_id), + logfile->lf_full_link_name, + logfile->lf_full_file_name); + } + else + { + fprintf(stderr, "%s\t: %s\n", + STRLOGNAME(logfile_id), + logfile->lf_full_file_name); + } succp = true; logfile->lf_state = RUN; CHK_LOGFILE(logfile); @@ -2245,12 +2318,18 @@ static void logfile_done( { switch(lf->lf_state) { case RUN: - CHK_LOGFILE(lf); - ss_dassert(lf->lf_npending_writes == 0); + CHK_LOGFILE(lf); + ss_dassert(lf->lf_npending_writes == 0); + /** fallthrough */ case INIT: - mlist_done(&lf->lf_blockbuf_list); - logfile_free_memory(lf); - lf->lf_state = DONE; + /** Test if list is initialized before freeing it */ + if (lf->lf_blockbuf_list.mlist_versno != 0) + { + mlist_done(&lf->lf_blockbuf_list); + } + logfile_free_memory(lf); + lf->lf_state = DONE; + /** fallthrough */ case DONE: case UNINIT: default: diff --git a/server/core/gateway.c b/server/core/gateway.c index 8e6dbb5ee..4131366a4 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -73,7 +73,9 @@ #include /** for procname */ -#define _GNU_SOURCE +#if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif extern char *program_invocation_name; extern char *program_invocation_short_name; @@ -174,6 +176,9 @@ static bool resolve_maxscale_conf_fname( char* cnf_file_arg); static bool resolve_maxscale_homedir( char** p_home_dir); + +static char* check_dir_access(char* dirname); + /** * Handler for SIGHUP signal. Reload the configuration for the * gateway. @@ -593,65 +598,45 @@ static bool resolve_maxscale_homedir( if (*p_home_dir != NULL) { log_context = strdup("Current working directory"); - goto check_home_dir; } check_home_dir: - if (*p_home_dir != NULL) - { - if (!file_is_readable(*p_home_dir)) - { - char* tailstr = "MaxScale doesn't have read permission " - "to MAXSCALE_HOME."; - char* logstr = (char*)malloc(strlen(log_context)+ - 1+ - strlen(tailstr)+ - 1); - snprintf(logstr, - strlen(log_context)+ - 1+ - strlen(tailstr)+1, - "%s:%s", - log_context, - tailstr); - print_log_n_stderr(true, true, logstr, logstr, 0); - free(logstr); - goto return_succp; - } - - if (!file_is_writable(*p_home_dir)) - { - char* tailstr = "MaxScale doesn't have write permission " - "to MAXSCALE_HOME. Exiting."; - char* logstr = (char*)malloc(strlen(log_context)+ - 1+ - strlen(tailstr)+ - 1); - snprintf(logstr, - strlen(log_context)+ - 1+ - strlen(tailstr)+1, - "%s:%s", - log_context, - tailstr); - print_log_n_stderr(true, true, logstr, logstr, 0); - free(logstr); - goto return_succp; - } - - if (!daemon_mode) - { - fprintf(stderr, - "Using %s as MAXSCALE_HOME = %s\n", - log_context, - tmp); - } - succp = true; - goto return_succp; - } - -return_succp: - free (tmp); + + if (*p_home_dir != NULL) + { + char* errstr; + + errstr = check_dir_access(*p_home_dir); + + if (errstr != NULL) + { + char* logstr = (char*)malloc(strlen(log_context)+ + 1+ + strlen(errstr)+ + 1); + + snprintf(logstr, + strlen(log_context)+ + 1+ + strlen(errstr)+1, + "%s: %s", + log_context, + errstr); + + print_log_n_stderr(true, true, logstr, logstr, 0); + + free(errstr); + free(logstr); + } + else if (!daemon_mode) + { + fprintf(stderr, + "Using %s as MAXSCALE_HOME = %s\n", + log_context, + tmp); + } + } + free (tmp); if (log_context != NULL) { @@ -668,6 +653,42 @@ return_succp: return succp; } +/** + * Check read and write accessibility to a directory. + * @param dirname directory to be checked + * + * @return NULL if directory can be read and written, an error message if either + * read or write is not permitted. + */ +static char* check_dir_access( + char* dirname) +{ + char* errstr = NULL; + + if (dirname == NULL) + { + errstr = strdup("Directory argument is NULL"); + goto retblock; + } + + if (!file_is_readable(dirname)) + { + errstr = strdup("MaxScale doesn't have read permission " + "to MAXSCALE_HOME."); + goto retblock; + } + + if (!file_is_writable(dirname)) + { + errstr = strdup("MaxScale doesn't have write permission " + "to MAXSCALE_HOME. Exiting."); + goto retblock; + } + +retblock: + return errstr; +} + /** * @node Provides error printing for non-formatted error strings. @@ -1378,6 +1399,44 @@ int main(int argc, char **argv) sprintf(mysql_home, "%s/mysql", home_dir); setenv("MYSQL_HOME", mysql_home, 1); } + else + { + char* log_context = strdup("Home directory command-line argument"); + char* errstr; + + errstr = check_dir_access(home_dir); + + if (errstr != NULL) + { + char* logstr = (char*)malloc(strlen(log_context)+ + 1+ + strlen(errstr)+ + 1); + + snprintf(logstr, + strlen(log_context)+ + 1+ + strlen(errstr)+1, + "%s: %s", + log_context, + errstr); + + print_log_n_stderr(true, true, logstr, logstr, 0); + + free(errstr); + free(logstr); + rc = MAXSCALE_HOMELESS; + goto return_main; + } + else if (!daemon_mode) + { + fprintf(stderr, + "Using %s as MAXSCALE_HOME = %s\n", + log_context, + home_dir); + } + free(log_context); + } /*< * Init Log Manager for MaxScale. @@ -1387,8 +1446,9 @@ int main(int argc, char **argv) * argv[0] */ { - char buf[1024]; - char *argv[8]; + char buf[1024]; + char *argv[8]; + bool succp; sprintf(buf, "%s/log", home_dir); mkdir(buf, 0777); @@ -1401,7 +1461,7 @@ int main(int argc, char **argv) argv[4] = "LOGFILE_MESSAGE,LOGFILE_ERROR" "LOGFILE_DEBUG,LOGFILE_TRACE"; argv[5] = NULL; - skygw_logmanager_init(5, argv); + succp = skygw_logmanager_init(5, argv); } else { @@ -1410,7 +1470,13 @@ int main(int argc, char **argv) argv[5] = "-l"; /*< write to syslog */ argv[6] = "LOGFILE_MESSAGE,LOGFILE_ERROR"; /*< ..these logs to syslog */ argv[7] = NULL; - skygw_logmanager_init(7, argv); + succp = skygw_logmanager_init(7, argv); + } + + if (!succp) + { + rc = MAXSCALE_BADCONFIG; + goto return_main; } } diff --git a/utils/skygw_utils.cc b/utils/skygw_utils.cc index 3699791c3..4a020d38e 100644 --- a/utils/skygw_utils.cc +++ b/utils/skygw_utils.cc @@ -320,6 +320,7 @@ mlist_t* mlist_init( list->mlist_nodecount_max = maxnodes; /** Set data deletion callback fun */ list->mlist_datadel = datadel; + if (name != NULL) { list->mlist_name = name; } @@ -345,6 +346,7 @@ mlist_t* mlist_init( CHK_MLIST_CURSOR(c); *cursor = c; } + list->mlist_versno = 2; /*< vresno != 0 means that list is initialized */ CHK_MLIST(list); return_list: diff --git a/utils/skygw_utils.h b/utils/skygw_utils.h index 309b9019f..6d2bc7b67 100644 --- a/utils/skygw_utils.h +++ b/utils/skygw_utils.h @@ -52,9 +52,7 @@ typedef struct mlist_st { bool mlist_deleted; size_t mlist_nodecount; size_t mlist_nodecount_max; /**< size limit. 0 == no limit */ -#if 1 size_t mlist_versno; -#endif bool mlist_flat; mlist_node_t* mlist_first; mlist_node_t* mlist_last; From a194c47b07805ea39315b72519ac10361f37206c Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Tue, 14 Oct 2014 12:33:56 +0200 Subject: [PATCH 22/39] Updated test_mysql_users Updated test_mysql_users --- server/core/test/test_mysql_users.c | 27 +++++++++++++++++++++----- server/modules/protocol/mysql_common.c | 8 +++++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/server/core/test/test_mysql_users.c b/server/core/test/test_mysql_users.c index a0b806623..1d0193c45 100644 --- a/server/core/test/test_mysql_users.c +++ b/server/core/test/test_mysql_users.c @@ -78,6 +78,7 @@ int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char /* 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); return 1; } @@ -108,6 +109,7 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor char *fetch_data; mysql_users = mysql_users_alloc(); + /* prepare the user@host data struct */ memset(&serv_addr, 0, sizeof(serv_addr)); memset(&key, 0, sizeof(key)); @@ -116,6 +118,7 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor 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) @@ -130,6 +133,7 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor /* 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; } @@ -139,6 +143,7 @@ int set_and_get_single_mysql_users(char *username, char *hostname, char *passwor 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; @@ -169,6 +174,7 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass } if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL) { fprintf(stderr, "service_alloc() failed\n"); + dcb_free(dcb); return 1; } @@ -177,6 +183,8 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass if (hostname) { if(!setipaddress(&client_addr.sin_addr, from)) { fprintf(stderr, "setipaddress failed for host [%s]\n", from); + free(service); + dcb_free(dcb); return 1; } } @@ -195,6 +203,10 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass ret = add_mysql_users_with_host_ipv4(mysql_users, username, hostname, password); if (!ret) { fprintf(stderr, "add_mysql_users_with_host_ipv4 passed(%s@%s, %s) FAILED\n", username, hostname, password); + users_free(mysql_users); + free(service); + dcb_free(dcb); + return 1; } else { char db_passwd[100]=""; @@ -208,6 +220,10 @@ int set_and_get_mysql_users_wildcards(char *username, char *hostname, char *pass ret = gw_find_mysql_user_password_sha1(username, db_passwd, dcb); } + users_free(mysql_users); + free(service); + dcb_free(dcb); + return ret; } @@ -223,7 +239,6 @@ int main() { 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"); @@ -238,6 +253,7 @@ int main() { 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"); @@ -247,6 +263,7 @@ int main() { 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); @@ -295,19 +312,19 @@ int main() { 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"); + ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.%", "y78764o", "192.3.2.1"); 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"); + ret = set_and_get_mysql_users_wildcards("pippo", "192.0.%.%", "1234567890123456789012345678901234567890", "192.3.2.1"); if (ret) fprintf(stderr, "\t-- Expecting no match\n"); assert(ret == 1); - ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "foo", "192.3.2.1"); + ret = set_and_get_mysql_users_wildcards("pippo", "192.%.%.%", "1234567890123456789012345678901234567890f8__uuo5", "192.3.2.1"); if (!ret) fprintf(stderr, "\t-- Expecting ok\n"); assert(ret == 0); - ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.%", "foo", "192.134.0.2"); + ret = set_and_get_mysql_users_wildcards("pippo", "192.0.0.%", "fo887778o", "192.134.0.2"); if (ret) fprintf(stderr, "\t-- Expecting no match\n"); assert(ret == 1); diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 3dbbe14be..c098263c2 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -1450,9 +1450,11 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, * The gateway_password represents the SHA1(SHA1(real_password)). * Please note: the real_password is unknown and SHA1(real_password) is unknown as well */ - - if (strlen(user_password)) - gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + int passwd_len=strlen(user_password); + if (passwd_len) { + passwd_len = (passwd_len <= (SHA_DIGEST_LENGTH * 2)) ? passwd_len : (SHA_DIGEST_LENGTH * 2); + gw_hex2bin(gateway_password, user_password, passwd_len); + } return 0; } else { From 9212effb86b72c052ac3fe27c1fa61849c61a4d4 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Tue, 14 Oct 2014 12:46:15 +0200 Subject: [PATCH 23/39] memory leak fixed memory leak fixed --- server/modules/protocol/mysql_client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index 06f83f3e1..92317cb40 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -558,6 +558,7 @@ static char* create_auth_fail_str( { sprintf(errstr, ferrstr, uname, hostaddr, (*sha1 == '\0' ? "NO" : "YES")); } + free(uname); retblock: return errstr; From 6237209bb26f0b546eca2189d62607fa93c28409 Mon Sep 17 00:00:00 2001 From: counterpoint Date: Tue, 14 Oct 2014 11:46:56 +0100 Subject: [PATCH 24/39] Add tests --- server/core/test/testbuffer.c | 6 +++ server/core/test/testdcb.c | 1 + server/core/test/testgwbitmask.c | 83 ++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 server/core/test/testgwbitmask.c diff --git a/server/core/test/testbuffer.c b/server/core/test/testbuffer.c index 87ebf858b..0ea2ca311 100644 --- a/server/core/test/testbuffer.c +++ b/server/core/test/testbuffer.c @@ -32,6 +32,7 @@ #include #include +#include /** * test1 Allocate a buffer and do lots of things @@ -41,6 +42,7 @@ static int test1() { GWBUF *buffer, *extra, *clone, *partclone, *transform; +HINT *hint; int size = 100; int bite1 = 35; int bite2 = 60; @@ -58,6 +60,10 @@ int buflen; ss_info_dassert(size == buflen, "Incorrect buffer size"); ss_info_dassert(0 == GWBUF_EMPTY(buffer), "Buffer should not be empty"); ss_info_dassert(GWBUF_IS_TYPE_UNDEFINED(buffer), "Buffer type should be undefined"); + ss_dfprintf(stderr, "\t..done\nSet a hint for the buffer"); + hint = hint_create_parameter(NULL, strdup("name"), "value"); + gwbuf_add_hint(buffer, hint); + ss_info_dassert(hint == buffer->hint, "Buffer should point to first and only hint"); ss_dfprintf(stderr, "\t..done\nSet a property for the buffer"); gwbuf_add_property(buffer, "name", "value"); ss_info_dassert(0 == strcmp("value", gwbuf_get_property(buffer, "name")), "Should now have correct property"); diff --git a/server/core/test/testdcb.c b/server/core/test/testdcb.c index 5f8e18601..1d26dfb17 100644 --- a/server/core/test/testdcb.c +++ b/server/core/test/testdcb.c @@ -51,6 +51,7 @@ int buflen; ss_dfprintf(stderr, "testdcb : creating buffer with type DCB_ROLE_SERVICE_LISTENER"); dcb = dcb_alloc(DCB_ROLE_SERVICE_LISTENER); + printDCB(dcb); ss_info_dassert(dcb_isvalid(dcb), "New DCB must be valid"); ss_dfprintf(stderr, "\t..done\nAllocated dcb."); clone = dcb_clone(dcb); diff --git a/server/core/test/testgwbitmask.c b/server/core/test/testgwbitmask.c new file mode 100644 index 000000000..f09dbae17 --- /dev/null +++ b/server/core/test/testgwbitmask.c @@ -0,0 +1,83 @@ +/* + * This file is distributed as part of MaxScale. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright SkySQL Ab 2014 + */ + +/** + * + * @verbatim + * Revision History + * + * Date Who Description + * 13-10-2014 Martin Brampton Initial implementation + * + * @endverbatim + */ + +#include +#include +#include + +#include + +#include + +/** + * test1 Allocate table of users and mess around with it + * + */ + +static int +test1() +{ +static GWBITMASK bitmask, another; +int i; + + /* Hint tests */ + ss_dfprintf(stderr, + "testgwbitmask : Initialise a bitmask"); + bitmask_init(&bitmask); + ss_info_dassert(BIT_LENGTH_INITIAL == bitmask.length, "Length should be initial length."); + for (i = 0; i < BIT_LENGTH_INITIAL; i++) { + ss_info_dassert(0 == bitmask_isset(&bitmask, i), "All bits should initially be zero"); + } + ss_info_dassert(0 != bitmask_isallclear(&bitmask), "Should be all clear"); + ss_dfprintf(stderr, "\t..done\nSet an arbitrary bit."); + bitmask_set(&bitmask, 17); + bitmask_copy(&another, &bitmask); + ss_info_dassert(0 != bitmask_isset(&another, 17), "Test bit should be set"); + ss_dfprintf(stderr, "\t..done\nClear the arbitrary bit."); + bitmask_clear(&bitmask, 17); + ss_info_dassert(0 == bitmask_isset(&bitmask, 17), "Test bit should be clear"); + ss_info_dassert(0 != bitmask_isallclear(&bitmask), "Should be all clear"); + ss_dfprintf(stderr, "\t..done\nFree the bitmask."); + bitmask_free(&bitmask); + ss_info_dassert(0 == bitmask.length, "Length should be zero after bit mask freed."); + ss_dfprintf(stderr, "\t..done\n"); + + return 0; + +} + +int main(int argc, char **argv) +{ +int result = 0; + + result += test1(); + + exit(result); +} + From 2a0233aa309c3176d3c0095de52e3ce6762328d2 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 14 Oct 2014 13:49:33 +0300 Subject: [PATCH 25/39] Updated MaxScale version to 1.0.2 --- macros.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macros.cmake b/macros.cmake index ce5a21ef9..3b75fcfa6 100644 --- a/macros.cmake +++ b/macros.cmake @@ -9,7 +9,7 @@ macro(set_maxscale_version) #MaxScale version number set(MAXSCALE_VERSION_MAJOR "1") set(MAXSCALE_VERSION_MINOR "0") - set(MAXSCALE_VERSION_PATCH "2") + set(MAXSCALE_VERSION_PATCH "2") set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}") set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}-beta") From 0ae522f1bd0fa1ffacc842edeb8e152a1acbd2f8 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Tue, 14 Oct 2014 12:53:31 +0200 Subject: [PATCH 26/39] Memory leak in getUsers() Memory leak in getUsers() when no users are loaded due to an error --- server/core/dbusers.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index cee42e74a..3b2b36361 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -119,8 +119,10 @@ USERS *newusers, *oldusers; i = getUsers(service, newusers); - if (i <= 0) + if (i <= 0) { + users_free(newusers); return i; + } spinlock_acquire(&service->spin); oldusers = service->users; From 9ed65759a27937371173151ba4e11922eba2bb02 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 14 Oct 2014 14:14:10 +0300 Subject: [PATCH 27/39] Changed missed references of SkySQL, Gateway and old emails and URLs to new versions. --- debian/changelog | 4 ++-- replication_listener/access_method_factory.cpp | 2 +- replication_listener/basic_content_handler.cpp | 2 +- replication_listener/basic_content_handler.h | 2 +- replication_listener/binary_log.cpp | 2 +- replication_listener/binlog_api.h | 2 +- replication_listener/binlog_driver.cpp | 2 +- replication_listener/binlog_driver.h | 2 +- replication_listener/binlog_event.cpp | 2 +- replication_listener/binlog_event.h | 2 +- replication_listener/gtid.cpp | 2 +- replication_listener/gtid.h | 2 +- replication_listener/listener_exception.h | 2 +- replication_listener/protocol.cpp | 2 +- replication_listener/tcp_driver.cpp | 2 +- replication_listener/tcp_driver.h | 2 +- replication_listener/tests/event_dump.cpp | 2 +- server/core/test/testbuffer.c | 2 +- server/core/test/testdcb.c | 2 +- server/core/test/testgwbitmask.c | 2 +- server/core/test/testhint.c | 2 +- server/core/test/testmodutil.c | 2 +- server/core/test/testpoll.c | 2 +- server/core/test/testserver.c | 2 +- server/core/test/testservice.c | 2 +- server/core/test/testusers.c | 2 +- server/modules/filter/test/Makefile | 4 ++-- .../table_replication_consistency.cpp | 2 +- table_replication_consistency/table_replication_consistency.h | 2 +- table_replication_consistency/table_replication_listener.cpp | 2 +- table_replication_consistency/table_replication_listener.h | 2 +- table_replication_consistency/table_replication_metadata.cpp | 2 +- table_replication_consistency/table_replication_metadata.h | 2 +- table_replication_consistency/table_replication_parser.cpp | 2 +- table_replication_consistency/table_replication_parser.h | 2 +- 35 files changed, 37 insertions(+), 37 deletions(-) mode change 100755 => 100644 server/modules/filter/test/Makefile diff --git a/debian/changelog b/debian/changelog index e416d995a..846f67a10 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,9 +2,9 @@ maxscale (1.0-beta) UNRELEASED; urgency=low * Beta release - -- Timofey Turenko Fri, 05 Jul 2014 14:00:00 +0200 + -- Timofey Turenko Fri, 05 Jul 2014 14:00:00 +0200 maxscale (0.7-1) UNRELEASED; urgency=low * Initial release. (Closes: #XXXXXX) - -- Timofey Turenko Tue, 11 Mar 2014 22:59:35 +0200 + -- Timofey Turenko Tue, 11 Mar 2014 22:59:35 +0200 diff --git a/replication_listener/access_method_factory.cpp b/replication_listener/access_method_factory.cpp index 7261b9355..b44f69692 100644 --- a/replication_listener/access_method_factory.cpp +++ b/replication_listener/access_method_factory.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA MariaDB Corporation change details: - Removed unnecessary file driver -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ #include "access_method_factory.h" diff --git a/replication_listener/basic_content_handler.cpp b/replication_listener/basic_content_handler.cpp index 9b209ab28..ffcc35fde 100644 --- a/replication_listener/basic_content_handler.cpp +++ b/replication_listener/basic_content_handler.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA MariaDB Corporation change details: - Added GTID event handler -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ diff --git a/replication_listener/basic_content_handler.h b/replication_listener/basic_content_handler.h index 5debfb672..7a83838af 100644 --- a/replication_listener/basic_content_handler.h +++ b/replication_listener/basic_content_handler.h @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA MariaDB Corporation change details: - Added GTID event handler -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ diff --git a/replication_listener/binary_log.cpp b/replication_listener/binary_log.cpp index 199cf65c4..20c87c896 100644 --- a/replication_listener/binary_log.cpp +++ b/replication_listener/binary_log.cpp @@ -27,7 +27,7 @@ MariaDB Corporation change details: - Added support for setting binlog position based on GTID - Added support for MySQL and MariDB server types -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ diff --git a/replication_listener/binlog_api.h b/replication_listener/binlog_api.h index fb6e24f77..33d32fd1d 100644 --- a/replication_listener/binlog_api.h +++ b/replication_listener/binlog_api.h @@ -27,7 +27,7 @@ MariaDB Corporation change details: - Added support for setting binlog position based on GTID - Added support for MySQL and MariDB server types -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ diff --git a/replication_listener/binlog_driver.cpp b/replication_listener/binlog_driver.cpp index 86c3ea954..81c019332 100644 --- a/replication_listener/binlog_driver.cpp +++ b/replication_listener/binlog_driver.cpp @@ -26,7 +26,7 @@ MariaDB Corporation change details: - Added support for GTID event handling for both MySQL and MariaDB -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ diff --git a/replication_listener/binlog_driver.h b/replication_listener/binlog_driver.h index 73e60587d..44f9fb3c4 100644 --- a/replication_listener/binlog_driver.h +++ b/replication_listener/binlog_driver.h @@ -27,7 +27,7 @@ MariaDB Corporation change details: - Added support for GTID event handling for both MySQL and MariaDB - Added support for setting binlog position based on GTID -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ diff --git a/replication_listener/binlog_event.cpp b/replication_listener/binlog_event.cpp index d1f4da802..d89142333 100644 --- a/replication_listener/binlog_event.cpp +++ b/replication_listener/binlog_event.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA MariaDB Corporation change details: - Added support for GTID event handling for both MySQL and MariaDB -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ diff --git a/replication_listener/binlog_event.h b/replication_listener/binlog_event.h index 3c8285044..45aa31a83 100644 --- a/replication_listener/binlog_event.h +++ b/replication_listener/binlog_event.h @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA MariaDB Corporation change details: - Added support for GTID event handling for both MySQL and MariaDB -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ #ifndef _BINLOG_EVENT_H diff --git a/replication_listener/gtid.cpp b/replication_listener/gtid.cpp index ed9d80bea..7091dfc92 100644 --- a/replication_listener/gtid.cpp +++ b/replication_listener/gtid.cpp @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com */ diff --git a/replication_listener/gtid.h b/replication_listener/gtid.h index 359ae9d04..218e2a30f 100644 --- a/replication_listener/gtid.h +++ b/replication_listener/gtid.h @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com */ diff --git a/replication_listener/listener_exception.h b/replication_listener/listener_exception.h index 7ff656ea8..b38312b58 100644 --- a/replication_listener/listener_exception.h +++ b/replication_listener/listener_exception.h @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com */ diff --git a/replication_listener/protocol.cpp b/replication_listener/protocol.cpp index 8d07f6877..317500ce8 100644 --- a/replication_listener/protocol.cpp +++ b/replication_listener/protocol.cpp @@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA MariaDB Corporation change details: - Added support for GTID event handling for both MySQL and MariaDB -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ #include diff --git a/replication_listener/tcp_driver.cpp b/replication_listener/tcp_driver.cpp index 216077249..a0aa88986 100644 --- a/replication_listener/tcp_driver.cpp +++ b/replication_listener/tcp_driver.cpp @@ -28,7 +28,7 @@ MariaDB Corporation change details: - Added support for starting binlog dump from GTID position - Added error handling using exceptions -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ #include "binlog_api.h" diff --git a/replication_listener/tcp_driver.h b/replication_listener/tcp_driver.h index 7d4d96c94..530249276 100644 --- a/replication_listener/tcp_driver.h +++ b/replication_listener/tcp_driver.h @@ -28,7 +28,7 @@ MariaDB Corporation change details: - Added support for starting binlog dump from GTID position - Added support for MariaDB server -Author: Jan Lindström (jan.lindstrom@skysql.com +Author: Jan Lindström (jan.lindstrom@mariadb.com */ diff --git a/replication_listener/tests/event_dump.cpp b/replication_listener/tests/event_dump.cpp index d9c415374..132ba6f8b 100644 --- a/replication_listener/tests/event_dump.cpp +++ b/replication_listener/tests/event_dump.cpp @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com */ diff --git a/server/core/test/testbuffer.c b/server/core/test/testbuffer.c index 0ea2ca311..ee8507161 100644 --- a/server/core/test/testbuffer.c +++ b/server/core/test/testbuffer.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/core/test/testdcb.c b/server/core/test/testdcb.c index 1d26dfb17..2703763f0 100644 --- a/server/core/test/testdcb.c +++ b/server/core/test/testdcb.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/core/test/testgwbitmask.c b/server/core/test/testgwbitmask.c index f09dbae17..86bad1245 100644 --- a/server/core/test/testgwbitmask.c +++ b/server/core/test/testgwbitmask.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/core/test/testhint.c b/server/core/test/testhint.c index 3d2241642..b615baced 100644 --- a/server/core/test/testhint.c +++ b/server/core/test/testhint.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/core/test/testmodutil.c b/server/core/test/testmodutil.c index e83facdc5..b37203ff4 100644 --- a/server/core/test/testmodutil.c +++ b/server/core/test/testmodutil.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/core/test/testpoll.c b/server/core/test/testpoll.c index aee799bb4..4d8d4cc04 100644 --- a/server/core/test/testpoll.c +++ b/server/core/test/testpoll.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/core/test/testserver.c b/server/core/test/testserver.c index 56a69e65d..3b05188ab 100644 --- a/server/core/test/testserver.c +++ b/server/core/test/testserver.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/core/test/testservice.c b/server/core/test/testservice.c index 2b12c8062..579bd617f 100644 --- a/server/core/test/testservice.c +++ b/server/core/test/testservice.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/core/test/testusers.c b/server/core/test/testusers.c index f407b273a..3f13cad9b 100644 --- a/server/core/test/testusers.c +++ b/server/core/test/testusers.c @@ -13,7 +13,7 @@ * this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright SkySQL Ab 2014 + * Copyright MariaDB Corporation Ab 2014 */ /** diff --git a/server/modules/filter/test/Makefile b/server/modules/filter/test/Makefile old mode 100755 new mode 100644 index 5eb6561f7..12546291d --- a/server/modules/filter/test/Makefile +++ b/server/modules/filter/test/Makefile @@ -1,4 +1,4 @@ -# This file is distributed as part of MaxScale form SkySQL. It is free +# This file is distributed as part of MaxScale form MariaDB Corporation. It is free # software: you can redistribute it and/or modify it under the terms of the # GNU General Public License as published by the Free Software Foundation, # version 2. @@ -12,7 +12,7 @@ # this program; if not, write to the Free Software Foundation, Inc., 51 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# Copyright SkySQL Ab 2014 +# Copyright MariaDB Corporation Ab 2014 include ../../../../build_gateway.inc diff --git a/table_replication_consistency/table_replication_consistency.cpp b/table_replication_consistency/table_replication_consistency.cpp index e29fc0cd7..0ef68aa27 100644 --- a/table_replication_consistency/table_replication_consistency.cpp +++ b/table_replication_consistency/table_replication_consistency.cpp @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com Created: 20-06-2013 Updated: diff --git a/table_replication_consistency/table_replication_consistency.h b/table_replication_consistency/table_replication_consistency.h index f900d1bf0..10d4451b6 100644 --- a/table_replication_consistency/table_replication_consistency.h +++ b/table_replication_consistency/table_replication_consistency.h @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com Created: 20-06-2013 Updated: diff --git a/table_replication_consistency/table_replication_listener.cpp b/table_replication_consistency/table_replication_listener.cpp index 283b49984..6c1502d70 100644 --- a/table_replication_consistency/table_replication_listener.cpp +++ b/table_replication_consistency/table_replication_listener.cpp @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com Created: 20-06-2013 Updated: */ diff --git a/table_replication_consistency/table_replication_listener.h b/table_replication_consistency/table_replication_listener.h index 2c1b31794..6cea875f4 100644 --- a/table_replication_consistency/table_replication_listener.h +++ b/table_replication_consistency/table_replication_listener.h @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com Created: 20-06-2013 Updated: diff --git a/table_replication_consistency/table_replication_metadata.cpp b/table_replication_consistency/table_replication_metadata.cpp index b25a350ed..0c9a4161f 100644 --- a/table_replication_consistency/table_replication_metadata.cpp +++ b/table_replication_consistency/table_replication_metadata.cpp @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com Created: 15-07-2013 Updated: */ diff --git a/table_replication_consistency/table_replication_metadata.h b/table_replication_consistency/table_replication_metadata.h index 910d63295..d29b5b9b1 100644 --- a/table_replication_consistency/table_replication_metadata.h +++ b/table_replication_consistency/table_replication_metadata.h @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com Created: 15-07-2013 Updated: */ diff --git a/table_replication_consistency/table_replication_parser.cpp b/table_replication_consistency/table_replication_parser.cpp index 999a9b083..42c92efaf 100644 --- a/table_replication_consistency/table_replication_parser.cpp +++ b/table_replication_consistency/table_replication_parser.cpp @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com Created: 20-06-2013 Updated: diff --git a/table_replication_consistency/table_replication_parser.h b/table_replication_consistency/table_replication_parser.h index 5a854e2f7..e60ad8576 100644 --- a/table_replication_consistency/table_replication_parser.h +++ b/table_replication_consistency/table_replication_parser.h @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -Author: Jan Lindström jan.lindstrom@skysql.com +Author: Jan Lindström jan.lindstrom@mariadb.com Created: 20-06-2013 Updated: From 38fb8cb52de13212bccdf883d0458932caabdf45 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 14 Oct 2014 14:20:47 +0300 Subject: [PATCH 28/39] Changed bugs.skysql.com to bugs.mariadb.com in README. --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index a939021d0..920c24994 100644 --- a/README +++ b/README @@ -29,7 +29,7 @@ issues and communicate with the MaxScale community. or use the [forum](http://groups.google.com/forum/#!forum/maxscale) interface Bugs can be reported in the MariaDB Corporation bugs database - [bug.skysql.com](http://bugs.skysql.com) + [bug.mariadb.com](http://bugs.mariadb.com) \section Building Building MaxScale From 80e4d733bdac5e8a70ee8fcbdeeaedd9dad7a55b Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Tue, 14 Oct 2014 15:43:37 +0200 Subject: [PATCH 29/39] MySQL authentication handles host wildcard MySQL authentication now authenticate hosts from mysql.user table that have wildcard: current implementation is: a.b.c.% a.b.%.% a.%.%.% --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1f6191473..ed69ddf2c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1-beta +1.0.2-beta From 6707d6d0cfd9e96fe2292ddc73ded3196d7f63d5 Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Tue, 14 Oct 2014 18:13:04 +0300 Subject: [PATCH 30/39] Complamentatry fix to that of #575. resolve_maxscale_homedir returned always false due to succp variable which wasn't updated in successful case. --- server/core/gateway.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/server/core/gateway.c b/server/core/gateway.c index 4131366a4..58a7153e5 100644 --- a/server/core/gateway.c +++ b/server/core/gateway.c @@ -539,7 +539,7 @@ return_succp: static bool resolve_maxscale_homedir( char** p_home_dir) { - bool succp = false; + bool succp; char* tmp; char* log_context = NULL; @@ -627,15 +627,25 @@ check_home_dir: free(errstr); free(logstr); + succp = false; } - else if (!daemon_mode) + else { - fprintf(stderr, - "Using %s as MAXSCALE_HOME = %s\n", - log_context, - tmp); + succp = true; + + if (!daemon_mode) + { + fprintf(stderr, + "Using %s as MAXSCALE_HOME = %s\n", + log_context, + tmp); + } } } + else + { + succp = false; + } free (tmp); if (log_context != NULL) @@ -1392,7 +1402,7 @@ int main(int argc, char **argv) { if (!resolve_maxscale_homedir(&home_dir)) { - ss_dassert(home_dir == NULL); + ss_dassert(home_dir != NULL); rc = MAXSCALE_HOMELESS; goto return_main; } From 56b82acb1b15bc779cfb72d0e14eece545a12ffd Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 14 Oct 2014 19:15:59 +0300 Subject: [PATCH 31/39] Fixed CMake builds overwriting MaxScale.cnf when installing after tests were built. --- CMakeLists.txt | 1 + server/CMakeLists.txt | 3 --- server/test/CMakeLists.txt | 3 --- 3 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 server/test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index e6fbec0d8..37cc1fc0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,7 @@ add_custom_target(buildtests add_custom_target(testall COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DBUILD_TYPE=Debug -DINSTALL_DIR=${CMAKE_BINARY_DIR} -DINSTALL_SYSTEM_FILES=N ${CMAKE_SOURCE_DIR} COMMAND make install + COMMAND cp -v ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null" COMMAND /bin/sh -c "make test || echo \"Test results written to: ${CMAKE_BINARY_DIR}/Testing/Temporary/\"" COMMAND killall maxscale diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index a42c625ae..6cd174190 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -1,6 +1,3 @@ add_subdirectory(core) add_subdirectory(modules) add_subdirectory(inih) -if(BUILD_TESTS) -add_subdirectory(test) -endif() \ No newline at end of file diff --git a/server/test/CMakeLists.txt b/server/test/CMakeLists.txt deleted file mode 100644 index 47eb22199..000000000 --- a/server/test/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -if(BUILD_TESTS) - install(FILES MaxScale_test.cnf DESTINATION etc RENAME MaxScale.cnf) -endif() From 6de751cd83bb36e2f70d3401ca05c7f4e6518eb0 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 14 Oct 2014 19:44:41 +0300 Subject: [PATCH 32/39] Fixed CMake configuration error with -DEMBEDDED_LIB= causing the library not being found. --- macros.cmake | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/macros.cmake b/macros.cmake index 3b75fcfa6..d8f1b7827 100644 --- a/macros.cmake +++ b/macros.cmake @@ -127,13 +127,17 @@ debugmsg("Search returned: ${MYSQL_DIR_LOC}") # Find the embedded mysql library if (DEFINED EMBEDDED_LIB) - debugmsg("Searching for the embedded library at: ${EMBEDDED_LIB}") - if(${CMAKE_VERSION} VERSION_LESS 2.12 ) - set(COMP_VAR PATH) - else() - set(COMP_VAR DIRECTORY) + if( NOT (IS_DIRECTORY ${EMBEDDED_LIB}) ) + debugmsg("EMBEDDED_LIB is not a directory: ${EMBEDDED_LIB}") + if(${CMAKE_VERSION} VERSION_LESS 2.12 ) + set(COMP_VAR PATH) + else() + set(COMP_VAR DIRECTORY) + endif() + get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} ${COMP_VAR}) + debugmsg("EMBEDDED_LIB directory component: ${EMBEDDED_LIB}") endif() - get_filename_component(EMBEDDED_LIB ${EMBEDDED_LIB} ${COMP_VAR}) + debugmsg("Searching for the embedded library at: ${EMBEDDED_LIB}") endif() if(STATIC_EMBEDDED) From 9c49cd87b1a44e0bfcdc5cf9ec00f31ab7355ae5 Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Wed, 15 Oct 2014 11:25:17 +0300 Subject: [PATCH 33/39] Fix to #571, http://bugs.mariadb.com/show_bug.cgi?id=571 In rwsplit router, merge multiple (query) buffers to one if necessary. --- server/modules/routing/readwritesplit/readwritesplit.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 505c7c5d1..07820b076 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -1708,6 +1708,12 @@ static int routeQuery( } goto retblock; } + /** If buffer is not contiguous, make it such */ + if (querybuf->next != NULL) + { + querybuf = gwbuf_make_contiguous(querybuf); + } + master_dcb = router_cli_ses->rses_master_ref->bref_dcb; CHK_DCB(master_dcb); From 87b14d973f479e2fc58f1ca064bcccec8422415a Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 15 Oct 2014 12:42:26 +0300 Subject: [PATCH 34/39] Running testall target with CMake doesn't overwrite the existing MaxScale.cnf anymore. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 37cc1fc0f..0c133c311 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,7 +144,7 @@ add_custom_target(buildtests add_custom_target(testall COMMAND ${CMAKE_COMMAND} -DDEPS_OK=Y -DBUILD_TESTS=Y -DBUILD_TYPE=Debug -DINSTALL_DIR=${CMAKE_BINARY_DIR} -DINSTALL_SYSTEM_FILES=N ${CMAKE_SOURCE_DIR} COMMAND make install - COMMAND cp -v ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf + COMMAND cp -vn ${CMAKE_SOURCE_DIR}/server/test/MaxScale_test.cnf ${CMAKE_BINARY_DIR}/etc/MaxScale.cnf COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -c ${CMAKE_BINARY_DIR} &>/dev/null" COMMAND /bin/sh -c "make test || echo \"Test results written to: ${CMAKE_BINARY_DIR}/Testing/Temporary/\"" COMMAND killall maxscale From 1a59e1b188df0a5eb85d6c32ad5d550bd75c9461 Mon Sep 17 00:00:00 2001 From: Mark Riddoch Date: Wed, 15 Oct 2014 12:39:34 +0100 Subject: [PATCH 35/39] Bug 559 - Remove password file before starting test_adminusers --- server/core/test/testadminusers.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server/core/test/testadminusers.c b/server/core/test/testadminusers.c index 4a67b1f5b..eb2ee8e40 100644 --- a/server/core/test/testadminusers.c +++ b/server/core/test/testadminusers.c @@ -266,6 +266,14 @@ int main(int argc, char **argv) { int result = 0; +char *home, buf[1024]; + + /* Unlink any existing password file before running this test */ + if ((home = getenv("MAXSCALE_HOME")) == NULL) + home = "/usr/local/skysql"; + sprintf(buf, "%s/etc/passwd", home); + if (strcmp(buf, "/etc/passwd") != 0) + unlink(buf); result += test1(); result += test2(); From fa278a2167573d9e8eb6c6cd363a122ac8c51ed8 Mon Sep 17 00:00:00 2001 From: Mark Riddoch Date: Wed, 15 Oct 2014 12:48:07 +0100 Subject: [PATCH 36/39] Bug 570 - memory manageing in hint parameters --- server/core/hint.c | 4 ++-- server/core/test/testhint.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/core/hint.c b/server/core/hint.c index 052c02486..0564625a4 100644 --- a/server/core/hint.c +++ b/server/core/hint.c @@ -116,7 +116,7 @@ HINT *hint; return head; hint->next = head; hint->type = HINT_PARAMETER; - hint->data = pname; + hint->data = strdup(pname); hint->value = strdup(value); return hint; } @@ -151,4 +151,4 @@ bool hint_exists( p_hint = &(*p_hint)->next; } return succp; -} \ No newline at end of file +} diff --git a/server/core/test/testhint.c b/server/core/test/testhint.c index b615baced..3ec5d9953 100644 --- a/server/core/test/testhint.c +++ b/server/core/test/testhint.c @@ -49,7 +49,7 @@ HINT *hint; hint = hint_create_parameter(NULL, strdup("name"), "value"); ss_info_dassert(NULL != hint, "New hint list should not be null"); ss_info_dassert(0 == strcmp("value", hint->value), "Hint value should be correct"); - ss_info_dassert(0 != hint_exists(hint, HINT_PARAMETER), "Hint of parameter type should exist"); + ss_info_dassert(0 != hint_exists(&hint, HINT_PARAMETER), "Hint of parameter type should exist"); ss_dfprintf(stderr, "\t..done\nFree hints."); if (NULL != hint) hint_free(hint); ss_dfprintf(stderr, "\t..done\n"); From a63e251d09011de00cf9c4e2829032ead7eb7b24 Mon Sep 17 00:00:00 2001 From: Mark Riddoch Date: Wed, 15 Oct 2014 13:03:12 +0100 Subject: [PATCH 37/39] Bug 431 - replace == with = --- server/modules/routing/readwritesplit/test/rwsplit.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/modules/routing/readwritesplit/test/rwsplit.sh b/server/modules/routing/readwritesplit/test/rwsplit.sh index fcca4ac37..7c9ec5edb 100755 --- a/server/modules/routing/readwritesplit/test/rwsplit.sh +++ b/server/modules/routing/readwritesplit/test/rwsplit.sh @@ -18,7 +18,7 @@ echo "" exit 1 fi -if [ "$#" == "$NARGS" ] +if [ "$#" = "$NARGS" ] then echo "CTest mode" TDIR=$7 #this is only used by CMake @@ -267,7 +267,7 @@ do break fi done -if [[ "$err" == "" ]] +if [[ "$err" = "" ]] then echo "TEST PASSED" >> $TLOG else @@ -293,7 +293,7 @@ do break fi done -if [[ "$err" == "" ]] +if [[ "$err" = "" ]] then echo "TEST PASSED" >> $TLOG else From 4acd85cf825eb23f32876d709855cb2c0be77f11 Mon Sep 17 00:00:00 2001 From: Mark Riddoch Date: Wed, 15 Oct 2014 13:26:00 +0100 Subject: [PATCH 38/39] Add missing trim() call to the server list code for monitors --- server/core/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/core/config.c b/server/core/config.c index 61bc6157d..181b009fc 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -817,7 +817,7 @@ int error_count = 0; int found = 0; while (obj1) { - if (strcmp(s, obj1->object) == 0 && + if (strcmp(trim(s), obj1->object) == 0 && obj->element && obj1->element) { found = 1; @@ -1449,7 +1449,7 @@ SERVER *server; int found = 0; while (obj1) { - if (strcmp(s, obj1->object) == 0 && + if (strcmp(trim(s), obj1->object) == 0 && obj->element && obj1->element) { found = 1; From b35b269b37a20a0a15a8b9e87dd31a48c6a8782d Mon Sep 17 00:00:00 2001 From: counterpoint Date: Wed, 15 Oct 2014 14:45:10 +0100 Subject: [PATCH 39/39] Added support for git-doc --- support/changelog.md | 2 + support/faq.md | 2 + support/gitdoc.json | 5 +++ support/guide/overview.md | 2 + support/reference/layout.md | 14 +++++++ support/reference/premium.md | 27 ++++++++++++++ support/tutorial.md | 71 ++++++++++++++++++++++++++++++++++++ 7 files changed, 123 insertions(+) create mode 100644 support/changelog.md create mode 100644 support/faq.md create mode 100644 support/gitdoc.json create mode 100644 support/guide/overview.md create mode 100644 support/reference/layout.md create mode 100644 support/reference/premium.md create mode 100644 support/tutorial.md diff --git a/support/changelog.md b/support/changelog.md new file mode 100644 index 000000000..d9917d9b7 --- /dev/null +++ b/support/changelog.md @@ -0,0 +1,2 @@ +### 2013/06/15 ++ Some example changes diff --git a/support/faq.md b/support/faq.md new file mode 100644 index 000000000..dcb005de6 --- /dev/null +++ b/support/faq.md @@ -0,0 +1,2 @@ +### is this a question? +An answer diff --git a/support/gitdoc.json b/support/gitdoc.json new file mode 100644 index 000000000..d1d45cd9c --- /dev/null +++ b/support/gitdoc.json @@ -0,0 +1,5 @@ +{ + "googleGroup": "group_name", + "irc": {"server": "irc.freenode.net", "channel": "#a_channel"}, + "domain": "yoursite.com" +} diff --git a/support/guide/overview.md b/support/guide/overview.md new file mode 100644 index 000000000..2d943c295 --- /dev/null +++ b/support/guide/overview.md @@ -0,0 +1,2 @@ +This directory is useful for many things, like how to install your software, if it has a CLI you +can tell people how to use it, any many other uses. diff --git a/support/reference/layout.md b/support/reference/layout.md new file mode 100644 index 000000000..622a999bc --- /dev/null +++ b/support/reference/layout.md @@ -0,0 +1,14 @@ +### Navigation +On the documentation/guide/reference pages, the sections created in your reference and guide +directories will be listed on the right as the main navigation links, you can have subsections too. +Any h3(###) lines you include in your reference/guide files will be added to the subsections under +the main section link. They will be hidden until you hover over the main section link or have +clicked the section link. + +### Headers +You can use any size headers you want, but it is adivised to use h3(###) and smaller, anything +bigger than h3(e.g. h2) is usually too big for the default layout. + +### Scrolling +When you scroll down the page the navigation will follow you if the screen is big enough for the +navigation to fit on the right side, otherwise it sits at the top. diff --git a/support/reference/premium.md b/support/reference/premium.md new file mode 100644 index 000000000..25500d5a6 --- /dev/null +++ b/support/reference/premium.md @@ -0,0 +1,27 @@ +### Premium repositories +Once you get premium, the plan you selected delegates the number of premium repositories you're +allowed to have. Premium repositories have many features not available without a premium plan. + +### Personally hosted repositories +The premium repositories you select are allowed to be hosted on their own domains, you can choose +a domain in your `support/gitdoc.json` file. Just add a `domain` field with your domain, and +point your domain at our site, and it will automatically load your repo. + +### Private repositories +Private repositories cannot be viewed without being set as a premium repository. + +### Custom CSS +You're premium repos can have custom layouts through CSS. Once you add a premium repo, simply create +the file `support/styles.css` and refresh your repo, when the page refreshes you'll be able to +see the custom CSS in action. + +### Branches +On premium repositories, you can select the branch you want to pull updates from, this is useful +if you plan to display the documentation for a specific version of your software. + +### Standard Git repos +Standard Git repositories from non Github servers are supported after you have a premium plan. +To add a standard repo to your account, add support for the repository(You can get the setup +details from your profile page.), after that go to your profile page and at the bottom will be +a form where you can fill out the information to add your repository. After that it can be updated +just like any other repository. diff --git a/support/tutorial.md b/support/tutorial.md new file mode 100644 index 000000000..f27a6b372 --- /dev/null +++ b/support/tutorial.md @@ -0,0 +1,71 @@ +### Introduction +After you run the command on the profile page a basic setup is created for you, including this +tutorial and a few other files. These files include content describing some of the details on +how to format the content. + +### Adding support +If you used the script to generate the support files, you can skip this section. + +In your repository to add support you'll need the `support` directory, inside this directory +you will need to create a `gitdoc.json` file. This file contains details about the repository. +``` +$ mkdir support/ +$ touch support/gitdoc.json +``` +The other files in the `support` directory are optional, only `gitdoc.json` is required. + +The following sections describe the information needed in the files. + +### gitdoc.json +There are a few fields in this file that make it easy to give your viewers extra details about +the community, as well as the domain for premium repos. + +#### googleGroup +This is a field you can use to give your viewers a link to your google group. Just set the field +to the name of your google group, and we'll create the link. It isn't required though, you can +leave it out safely. + +#### irc +This is a field you can use to give your viewers the details to join your irc channel. To use it +set an `object` with two fields. One of the fields is `server`, this is the server address for the +irc network(e.g. `irc.freenode.net` for the freenode network). The next is the `channel` field, +this tells the viewers the specific channel for your community. The channel requires you to +include the prefix character though(e.g. #, &, +, !), since there are multiple. + +#### domain +This is a field you can use if your repository is premium. It tells us the name of the domain +for your repo, so we can get your repo if we detect a custom domain. You can ignore it, or just +set a placeholder if it's not premium yet. + +#### analytics +When you view the repo from a custom premium domain, if this field is given it'll include the +Google Analytics snippet to track page views. This value should be your GA web property ID. + +### changelog.md +This file is just a markdown file displaying the changelog for your repository. For details on +the markdown, view the default documentation created. This file can be safely ignored if you don't +want to include a changelog page. + +### faq.md +This file is just a markdown file displaying the frequently asked questions for your repository. +For details on the markdown, view the default documentation created. This file can be safely +ignored if you don't want to include a faq page. + +### tutorial.md +This file is just a markdown file displaying the tutorial for your repository. For details on the +markdown, view the default documentation created. This file can be safely ignored if you don't +want to include a tutorial page. + +### styles.css +This file is used when your repository is premium to display custom layouts for your viewers. It +can be safely ignored, or just as a place holder if the repo is not premium yet. + +### reference/ +This directory is used to hold the markdown files for the documentation/reference page. Every file +in this directory will be added as a section to the documentation with the section titled after +the file name, so make sure it's readable. + +### guide/ +This directory is used to hold the markdown files for the documentation/guide page. Every file in this +directory will be added as a section to the guide with the section titled after the file name, so +make sure it's readable.