Commit 83c4523f authored by Marko Mäkelä's avatar Marko Mäkelä

Merge 10.4 into 10.5

parents 88f38661 69bd2c88
...@@ -72,10 +72,6 @@ static my_bool non_blocking_api_enabled= 0; ...@@ -72,10 +72,6 @@ static my_bool non_blocking_api_enabled= 0;
#include "../tests/nonblock-wrappers.h" #include "../tests/nonblock-wrappers.h"
#endif #endif
/* Use cygwin for --exec and --system before 5.0 */
#if MYSQL_VERSION_ID < 50000
#define USE_CYGWIN
#endif
#define MAX_VAR_NAME_LENGTH 256 #define MAX_VAR_NAME_LENGTH 256
#define MAX_COLUMNS 256 #define MAX_COLUMNS 256
...@@ -620,7 +616,6 @@ const char *get_errname_from_code (uint error_code); ...@@ -620,7 +616,6 @@ const char *get_errname_from_code (uint error_code);
int multi_reg_replace(struct st_replace_regex* r,char* val); int multi_reg_replace(struct st_replace_regex* r,char* val);
#ifdef _WIN32 #ifdef _WIN32
void free_tmp_sh_file();
void free_win_path_patterns(); void free_win_path_patterns();
#endif #endif
...@@ -1458,7 +1453,6 @@ void free_used_memory() ...@@ -1458,7 +1453,6 @@ void free_used_memory()
free_re(); free_re();
my_free(read_command_buf); my_free(read_command_buf);
#ifdef _WIN32 #ifdef _WIN32
free_tmp_sh_file();
free_win_path_patterns(); free_win_path_patterns();
#endif #endif
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -3190,33 +3184,6 @@ void do_source(struct st_command *command) ...@@ -3190,33 +3184,6 @@ void do_source(struct st_command *command)
} }
#if defined _WIN32
#ifdef USE_CYGWIN
/* Variables used for temporary sh files used for emulating Unix on Windows */
char tmp_sh_name[64], tmp_sh_cmd[70];
#endif
void init_tmp_sh_file()
{
#ifdef USE_CYGWIN
/* Format a name for the tmp sh file that is unique for this process */
my_snprintf(tmp_sh_name, sizeof(tmp_sh_name), "tmp_%d.sh", getpid());
/* Format the command to execute in order to run the script */
my_snprintf(tmp_sh_cmd, sizeof(tmp_sh_cmd), "sh %s", tmp_sh_name);
#endif
}
void free_tmp_sh_file()
{
#ifdef USE_CYGWIN
my_delete(tmp_sh_name, MYF(0));
#endif
}
#endif
static void init_builtin_echo(void) static void init_builtin_echo(void)
{ {
#ifdef _WIN32 #ifdef _WIN32
...@@ -3332,14 +3299,12 @@ void do_exec(struct st_command *command) ...@@ -3332,14 +3299,12 @@ void do_exec(struct st_command *command)
} }
#ifdef _WIN32 #ifdef _WIN32
#ifndef USE_CYGWIN
/* Replace /dev/null with NUL */ /* Replace /dev/null with NUL */
while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0) while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0)
; ;
/* Replace "closed stdout" with non existing output fd */ /* Replace "closed stdout" with non existing output fd */
while(replace(&ds_cmd, ">&-", 3, ">&4", 3) == 0) while(replace(&ds_cmd, ">&-", 3, ">&4", 3) == 0)
; ;
#endif
#endif #endif
if (disable_result_log) if (disable_result_log)
...@@ -3498,13 +3463,7 @@ int do_modify_var(struct st_command *command, ...@@ -3498,13 +3463,7 @@ int do_modify_var(struct st_command *command,
int my_system(DYNAMIC_STRING* ds_cmd) int my_system(DYNAMIC_STRING* ds_cmd)
{ {
#if defined _WIN32 && defined USE_CYGWIN
/* Dump the command into a sh script file and execute with system */
str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length);
return system(tmp_sh_cmd);
#else
return system(ds_cmd->str); return system(ds_cmd->str);
#endif
} }
...@@ -3538,12 +3497,10 @@ void do_system(struct st_command *command) ...@@ -3538,12 +3497,10 @@ void do_system(struct st_command *command)
do_eval(&ds_cmd, command->first_argument, command->end, !is_windows); do_eval(&ds_cmd, command->first_argument, command->end, !is_windows);
#ifdef _WIN32 #ifdef _WIN32
#ifndef USE_CYGWIN
/* Replace /dev/null with NUL */ /* Replace /dev/null with NUL */
while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0) while(replace(&ds_cmd, "/dev/null", 9, "NUL", 3) == 0)
; ;
#endif #endif
#endif
DBUG_PRINT("info", ("running system command '%s' as '%s'", DBUG_PRINT("info", ("running system command '%s' as '%s'",
...@@ -5012,13 +4969,34 @@ int query_get_string(MYSQL* mysql, const char* query, ...@@ -5012,13 +4969,34 @@ int query_get_string(MYSQL* mysql, const char* query,
} }
#ifdef _WIN32
#define SIGKILL 9
#include <my_minidump.h>
static int my_kill(int pid, int sig) static int my_kill(int pid, int sig)
{ {
DBUG_PRINT("info", ("Killing server, pid: %d", pid));
#ifdef _WIN32
#define SIGKILL 9 /* ignored anyway, see below */
HANDLE proc; HANDLE proc;
if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL) if (sig == SIGABRT)
{
/*
Create a minidump. If process is being debugged, debug break
Otherwise, terminate.
*/
verbose_msg("Aborting %d",pid);
my_create_minidump(pid,TRUE);
proc= OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if(!proc)
return -1;
BOOL debugger_present;
if (CheckRemoteDebuggerPresent(proc,&debugger_present) && debugger_present)
{
if (DebugBreakProcess(proc))
{
CloseHandle(proc);
return 0;
}
}
}
else if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL)
return -1; return -1;
if (sig == 0) if (sig == 0)
{ {
...@@ -5029,12 +5007,30 @@ static int my_kill(int pid, int sig) ...@@ -5029,12 +5007,30 @@ static int my_kill(int pid, int sig)
(void)TerminateProcess(proc, 201); (void)TerminateProcess(proc, 201);
CloseHandle(proc); CloseHandle(proc);
return 1; return 1;
#else
return kill(pid, sig);
#endif
} }
/* Wait until process is gone, with timeout */
static int wait_until_dead(int pid, int timeout)
{
HANDLE proc= OpenProcess(SYNCHRONIZE, FALSE, pid);
if (!proc)
return 0; /* already dead */
DBUG_ASSERT(timeout >= 0);
DBUG_ASSERT(timeout <= UINT_MAX/1000);
DWORD wait_result= WaitForSingleObject(proc, (DWORD)timeout*1000);
CloseHandle(proc);
return (int)wait_result;
}
#else /* !_WIN32 */
static int my_kill(int pid, int sig)
{
DBUG_PRINT("info", ("Killing server, pid: %d", pid));
return kill(pid, sig);
}
/* /*
Shutdown the server of current connection and Shutdown the server of current connection and
...@@ -5069,6 +5065,7 @@ static int wait_until_dead(int pid, int timeout) ...@@ -5069,6 +5065,7 @@ static int wait_until_dead(int pid, int timeout)
} }
DBUG_RETURN(1); // Did not die DBUG_RETURN(1); // Did not die
} }
#endif /* _WIN32 */
void do_shutdown_server(struct st_command *command) void do_shutdown_server(struct st_command *command)
...@@ -9185,10 +9182,7 @@ int main(int argc, char **argv) ...@@ -9185,10 +9182,7 @@ int main(int argc, char **argv)
init_builtin_echo(); init_builtin_echo();
#ifdef _WIN32 #ifdef _WIN32
#ifndef USE_CYGWIN
is_windows= 1; is_windows= 1;
#endif
init_tmp_sh_file();
init_win_path_patterns(); init_win_path_patterns();
#endif #endif
......
/* Copyright (c) 2021, MariaDB Corporation
This program 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 of the License.
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 St, Fifth Floor, Boston, MA 02110-1335 USA */
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
BOOL my_create_minidump(DWORD pid, BOOL verbose);
#ifdef __cplusplus
}
#endif
Subproject commit 42cb1e442c43902e2866bea38d15f2ed1f5d38b3 Subproject commit b99172386a740ef0c8136e9a6cd7d9ad9a77b31f
...@@ -19,7 +19,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) ...@@ -19,7 +19,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
IF (WIN32) IF (WIN32)
ADD_EXECUTABLE(my_safe_process safe_process_win.cc) ADD_EXECUTABLE(my_safe_process safe_process_win.cc)
ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc) ADD_EXECUTABLE(my_safe_kill safe_kill_win.cc)
TARGET_LINK_LIBRARIES(my_safe_kill dbghelp psapi) TARGET_INCLUDE_DIRECTORIES(my_safe_kill PRIVATE ${CMAKE_SOURCE_DIR}/include)
TARGET_LINK_LIBRARIES(my_safe_kill mysys psapi)
ELSE() ELSE()
ADD_EXECUTABLE(my_safe_process safe_process.cc) ADD_EXECUTABLE(my_safe_process safe_process.cc)
ENDIF() ENDIF()
......
...@@ -26,19 +26,7 @@ ...@@ -26,19 +26,7 @@
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <psapi.h> #include <psapi.h>
#include <my_minidump.h>
#ifdef _MSC_VER
/* Silence warning in OS header dbghelp.h */
#pragma warning(push)
#pragma warning(disable : 4091)
#endif
#include <dbghelp.h>
#ifdef _MSC_VER
/* Silence warning in OS header dbghelp.h */
#pragma warning(pop)
#endif
#include <tlhelp32.h> #include <tlhelp32.h>
#include <vector> #include <vector>
...@@ -64,106 +52,13 @@ static std::vector<DWORD> find_children(DWORD pid) ...@@ -64,106 +52,13 @@ static std::vector<DWORD> find_children(DWORD pid)
return children; return children;
} }
void dump_single_process(DWORD pid)
{
HANDLE file = 0;
HANDLE process= 0;
DWORD size= MAX_PATH;
char path[MAX_PATH];
char working_dir[MAX_PATH];
char tmpname[MAX_PATH];
char *filename= 0;
process= OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (!process)
{
fprintf(stderr, "safe_kill : cannot open process pid=%lu to create dump, last error %lu\n",
pid, GetLastError());
goto exit;
}
if (QueryFullProcessImageName(process, 0, path, &size) == 0)
{
fprintf(stderr, "safe_kill : cannot read process path for pid %lu, last error %lu\n",
pid, GetLastError());
goto exit;
}
filename= strrchr(path, '\\');
if (filename)
{
filename++;
// We are not interested in dump of some proceses (my_safe_process.exe,cmd.exe)
// since they are only used to start up other programs.
// We're interested however in their children;
const char *exclude_programs[] = {"my_safe_process.exe","cmd.exe", 0};
for(size_t i=0; exclude_programs[i]; i++)
if (_stricmp(filename, exclude_programs[i]) == 0)
goto exit;
}
else
filename= path;
// Add .dmp extension
char *p;
if ((p= strrchr(filename, '.')) == 0)
p= filename + strlen(filename);
strncpy(p, ".dmp", path + MAX_PATH - p);
// f file with this name exist, generate unique name with .dmp extension
if (GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES)
{
if (!GetTempFileName(".", filename, 0, tmpname))
{
fprintf(stderr, "GetTempFileName failed, last error %lu", GetLastError());
goto exit;
}
strncat_s(tmpname, ".dmp", sizeof(tmpname));
filename= tmpname;
}
if (!GetCurrentDirectory(MAX_PATH, working_dir))
{
fprintf(stderr, "GetCurrentDirectory failed, last error %lu", GetLastError());
goto exit;
}
file= CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (file == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "safe_kill : CreateFile() failed for file %s, working dir %s, last error = %lu\n",
filename, working_dir, GetLastError());
goto exit;
}
if (!MiniDumpWriteDump(process, pid, file, MiniDumpNormal, 0, 0, 0))
{
fprintf(stderr, "Failed to write minidump to %s, working dir %s, last error %lu\n",
filename, working_dir, GetLastError());
goto exit;
}
fprintf(stderr, "Minidump written to %s, directory %s\n", filename, working_dir);
exit:
if (process != 0 && process != INVALID_HANDLE_VALUE)
CloseHandle(process);
if (file != 0 && file != INVALID_HANDLE_VALUE)
CloseHandle(file);
}
static int create_dump(DWORD pid, int recursion_depth= 5) static int create_dump(DWORD pid, int recursion_depth= 5)
{ {
if (recursion_depth < 0) if (recursion_depth < 0)
return 0; return 0;
dump_single_process(pid); my_create_minidump(pid, TRUE);
std::vector<DWORD> children= find_children(pid); std::vector<DWORD> children= find_children(pid);
for(size_t i=0; i < children.size(); i++) for(size_t i=0; i < children.size(); i++)
create_dump(children[i], recursion_depth -1); create_dump(children[i], recursion_depth -1);
......
...@@ -38,34 +38,6 @@ DROP TABLE t1; ...@@ -38,34 +38,6 @@ DROP TABLE t1;
DROP TABLE ten; DROP TABLE ten;
connection node_1; connection node_1;
SET @value=REPEAT (1,5001); SET @value=REPEAT (1,5001);
CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb;
INSERT IGNORE INTO t VALUES(@value);
Warnings:
Warning 1265 Data truncated for column 'a' at row 1
SELECT COUNT(*) FROM t;
COUNT(*)
1
connection node_2;
SELECT COUNT(*) FROM t;
COUNT(*)
1
connection node_1;
DROP TABLE t;
CREATE TABLE t (a VARCHAR(5000)) engine=innodb;
INSERT IGNORE INTO t VALUES(@value);
Warnings:
Warning 1265 Data truncated for column 'a' at row 1
SELECT COUNT(*) FROM t;
COUNT(*)
1
connection node_2;
SELECT COUNT(*) FROM t;
COUNT(*)
1
connection node_1;
DROP TABLE t;
connection node_1;
SET @value=REPEAT (1,5001);
CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8; CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb DEFAULT CHARSET=utf8;
INSERT IGNORE INTO t VALUES(@value); INSERT IGNORE INTO t VALUES(@value);
Warnings: Warnings:
......
...@@ -60,29 +60,6 @@ SELECT COUNT(f1) = 1000 FROM t1 WHERE MATCH(f1) AGAINST ('abcdefjhk'); ...@@ -60,29 +60,6 @@ SELECT COUNT(f1) = 1000 FROM t1 WHERE MATCH(f1) AGAINST ('abcdefjhk');
DROP TABLE t1; DROP TABLE t1;
DROP TABLE ten; DROP TABLE ten;
#
# MDEV-24978 : SIGABRT in __libc_message
#
--connection node_1
SET @value=REPEAT (1,5001);
CREATE TABLE t (a VARCHAR(5000),FULLTEXT (a)) engine=innodb;
INSERT IGNORE INTO t VALUES(@value);
SELECT COUNT(*) FROM t;
--connection node_2
SELECT COUNT(*) FROM t;
--connection node_1
DROP TABLE t;
CREATE TABLE t (a VARCHAR(5000)) engine=innodb;
INSERT IGNORE INTO t VALUES(@value);
SELECT COUNT(*) FROM t;
--connection node_2
SELECT COUNT(*) FROM t;
--connection node_1
DROP TABLE t;
# #
# Case 2: UTF-8 # Case 2: UTF-8
......
...@@ -55,6 +55,7 @@ IF (WIN32) ...@@ -55,6 +55,7 @@ IF (WIN32)
my_winerr.c my_winerr.c
my_winfile.c my_winfile.c
my_conio.c my_conio.c
my_minidump.cc
my_win_popen.cc) my_win_popen.cc)
ENDIF() ENDIF()
...@@ -173,7 +174,7 @@ IF(HAVE_BFD_H) ...@@ -173,7 +174,7 @@ IF(HAVE_BFD_H)
ENDIF(HAVE_BFD_H) ENDIF(HAVE_BFD_H)
IF (WIN32) IF (WIN32)
TARGET_LINK_LIBRARIES(mysys IPHLPAPI) TARGET_LINK_LIBRARIES(mysys iphlpapi dbghelp)
ENDIF(WIN32) ENDIF(WIN32)
# Need explicit pthread for gcc -fsanitize=address # Need explicit pthread for gcc -fsanitize=address
......
/* Copyright (c) 2021, MariaDB Corporation
This program 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 of the License.
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 St, Fifth Floor, Boston, MA 02110-1335 USA */
#include <windows.h>
#include <dbghelp.h>
#include <stdio.h>
#include <my_minidump.h>
#define VERBOSE(fmt,...) \
if (verbose) { fprintf(stderr, "my_create_minidump : " fmt,__VA_ARGS__); }
extern "C" BOOL my_create_minidump(DWORD pid, BOOL verbose)
{
HANDLE file = 0;
HANDLE process= 0;
DWORD size= MAX_PATH;
char path[MAX_PATH];
char working_dir[MAX_PATH];
char tmpname[MAX_PATH];
char *filename= 0;
bool ret= FALSE;
process= OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (!process)
{
VERBOSE("cannot open process pid=%lu to create dump, last error %lu\n",
pid, GetLastError());
goto exit;
}
if (QueryFullProcessImageName(process, 0, path, &size) == 0)
{
VERBOSE("cannot read process path for pid %lu, last error %lu\n",
pid, GetLastError());
goto exit;
}
filename= strrchr(path, '\\');
if (filename)
{
filename++;
// We are not interested in dump of some proceses (my_safe_process.exe,cmd.exe)
// since they are only used to start up other programs.
// We're interested however in their children;
const char *exclude_programs[] = {"my_safe_process.exe","cmd.exe", 0};
for(size_t i=0; exclude_programs[i]; i++)
if (_stricmp(filename, exclude_programs[i]) == 0)
goto exit;
}
else
filename= path;
// Add .dmp extension
char *p;
if ((p= strrchr(filename, '.')) == 0)
p= filename + strlen(filename);
strncpy(p, ".dmp", path + MAX_PATH - p);
// Íf file with this name exist, generate unique name with .dmp extension
if (GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES)
{
if (!GetTempFileName(".", filename, 0, tmpname))
{
fprintf(stderr, "GetTempFileName failed, last error %lu", GetLastError());
goto exit;
}
strncat_s(tmpname, ".dmp", sizeof(tmpname));
filename= tmpname;
}
if (!GetCurrentDirectory(MAX_PATH, working_dir))
{
VERBOSE("GetCurrentDirectory failed, last error %lu", GetLastError());
goto exit;
}
file= CreateFile(filename, GENERIC_READ | GENERIC_WRITE,
0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (file == INVALID_HANDLE_VALUE)
{
VERBOSE("CreateFile() failed for file %s, working dir %s, last error = %lu\n",
filename, working_dir, GetLastError());
goto exit;
}
if (!MiniDumpWriteDump(process, pid, file, MiniDumpNormal, 0, 0, 0))
{
VERBOSE("Failed to write minidump to %s, working dir %s, last error %lu\n",
filename, working_dir, GetLastError());
goto exit;
}
VERBOSE("Minidump written to %s, directory %s\n", filename, working_dir);
ret= TRUE;
exit:
if (process != 0 && process != INVALID_HANDLE_VALUE)
CloseHandle(process);
if (file != 0 && file != INVALID_HANDLE_VALUE)
CloseHandle(file);
return ret;
}
...@@ -1065,8 +1065,9 @@ check_for_dhparams() ...@@ -1065,8 +1065,9 @@ check_for_dhparams()
# #
verify_ca_matches_cert() verify_ca_matches_cert()
{ {
local ca_path="$1" local ca="$1"
local cert_path="$2" local cert="$2"
local path=${3:-0}
# If the openssl utility is not installed, then # If the openssl utility is not installed, then
# we will not do this certificate check: # we will not do this certificate check:
...@@ -1075,8 +1076,15 @@ verify_ca_matches_cert() ...@@ -1075,8 +1076,15 @@ verify_ca_matches_cert()
return return
fi fi
if ! "$OPENSSL_BINARY" verify -verbose -CAfile "$ca_path" "$cert_path" >/dev/null 2>&1 local not_match=0
then
if [ $path -eq 0 ]; then
"$OPENSSL_BINARY" verify -verbose -CAfile "$ca" "$cert" >/dev/null 2>&1 || not_match=1
else
"$OPENSSL_BINARY" verify -verbose -CApath "$ca" "$cert" >/dev/null 2>&1 || not_match=1
fi
if [ $not_match -eq 1 ]; then
wsrep_log_error "******** FATAL ERROR ********************************************" wsrep_log_error "******** FATAL ERROR ********************************************"
wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *" wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *"
wsrep_log_error "* It does not appear that the certificate was issued by the CA. *" wsrep_log_error "* It does not appear that the certificate was issued by the CA. *"
......
...@@ -34,6 +34,7 @@ ssyslog="" ...@@ -34,6 +34,7 @@ ssyslog=""
ssystag="" ssystag=""
BACKUP_PID="" BACKUP_PID=""
tcert="" tcert=""
tpath=0
tpem="" tpem=""
tkey="" tkey=""
tmode="DISABLED" tmode="DISABLED"
...@@ -85,7 +86,6 @@ readonly SECRET_TAG="secret" ...@@ -85,7 +86,6 @@ readonly SECRET_TAG="secret"
# Required for backup locks # Required for backup locks
# For backup locks it is 1 sent by joiner # For backup locks it is 1 sent by joiner
# 5.6.21 PXC and later can't donate to an older joiner
sst_ver=1 sst_ver=1
if [ -n "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then if [ -n "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then
...@@ -339,64 +339,83 @@ get_transfer() ...@@ -339,64 +339,83 @@ get_transfer()
fi fi
fi fi
CN_option=",commonname=''"
if [ $encrypt -eq 2 ]; then if [ $encrypt -eq 2 ]; then
wsrep_log_info "Using openssl based encryption with socat: with crt and pem" wsrep_log_info "Using openssl based encryption with socat: with crt and pem"
if [ -z "$tpem" -o -z "$tcert" ]; then if [ -z "$tpem" -o -z "$tcert" ]; then
wsrep_log_error "Both PEM and CRT files required" wsrep_log_error \
"Both PEM file and CRT file (or path) are required"
exit 22 exit 22
fi fi
if [ ! -r "$tpem" -o ! -r "$tcert" ]; then if [ ! -r "$tpem" -o ! -r "$tcert" ]; then
wsrep_log_error "Both PEM and CRT files must be readable" wsrep_log_error \
"Both PEM file and CRT file (or path) must be readable"
exit 22 exit 22
fi fi
verify_ca_matches_cert "$tcert" "$tpem" verify_ca_matches_cert "$tcert" "$tpem" $tpath
tcmd="$tcmd,cert='$tpem',cafile='$tcert'$sockopt" if [ $tpath -eq 0 ]; then
tcmd="$tcmd,cert='$tpem',cafile='$tcert'"
else
tcmd="$tcmd,cert='$tpem',capath='$tcert'"
fi
stagemsg="$stagemsg-OpenSSL-Encrypted-2" stagemsg="$stagemsg-OpenSSL-Encrypted-2"
wsrep_log_info "$action with cert=$tpem, cafile=$tcert" wsrep_log_info "$action with cert=$tpem, ca=$tcert"
elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then
wsrep_log_info "Using openssl based encryption with socat: with key and crt" wsrep_log_info "Using openssl based encryption with socat: with key and crt"
if [ -z "$tpem" -o -z "$tkey" ]; then if [ -z "$tpem" -o -z "$tkey" ]; then
wsrep_log_error "Both certificate and key files required" wsrep_log_error "Both certificate file (or path) " \
"and key file are required"
exit 22 exit 22
fi fi
if [ ! -r "$tpem" -o ! -r "$tkey" ]; then if [ ! -r "$tpem" -o ! -r "$tkey" ]; then
wsrep_log_error "Both certificate and key files must be readable" wsrep_log_error "Both certificate file (or path) " \
"and key file must be readable"
exit 22 exit 22
fi fi
verify_cert_matches_key "$tpem" "$tkey" verify_cert_matches_key "$tpem" "$tkey"
stagemsg="$stagemsg-OpenSSL-Encrypted-3" stagemsg="$stagemsg-OpenSSL-Encrypted-3"
if [ -z "$tcert" ]; then if [ -z "$tcert" ]; then
if [ $encrypt -eq 4 ]; then if [ $encrypt -eq 4 ]; then
wsrep_log_error "Peer certificate required if encrypt=4" wsrep_log_error \
"Peer certificate file (or path) required if encrypt=4"
exit 22 exit 22
fi fi
# no verification # no verification
tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0$sockopt" CN_option=""
tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0"
wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0" wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0"
else else
# CA verification # CA verification
if [ ! -r "$tcert" ]; then if [ ! -r "$tcert" ]; then
wsrep_log_error "Certificate file must be readable" wsrep_log_error "Certificate file or path must be readable"
exit 22 exit 22
fi fi
verify_ca_matches_cert "$tcert" "$tpem" verify_ca_matches_cert "$tcert" "$tpem" $tpath
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'"
elif [ $encrypt -eq 4 ]; then elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' -o $encrypt -eq 4 ]
then
CN_option=",commonname=''" CN_option=",commonname=''"
elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
CN_option=',commonname=localhost' CN_option=',commonname=localhost'
else else
CN_option=",commonname='$WSREP_SST_OPT_HOST_UNESCAPED'" CN_option=",commonname='$WSREP_SST_OPT_HOST_UNESCAPED'"
fi fi
tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt" if [ $tpath -eq 0 ]; then
wsrep_log_info "$action with cert=$tpem, key=$tkey, cafile=$tcert" tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'"
else
tcmd="$tcmd,cert='$tpem',key='$tkey',capath='$tcert'"
fi
wsrep_log_info "$action with cert=$tpem, key=$tkey, ca=$tcert"
fi fi
else else
wsrep_log_info "Unknown encryption mode: encrypt=$encrypt" wsrep_log_info "Unknown encryption mode: encrypt=$encrypt"
exit 22 exit 22
fi fi
tcmd="$tcmd$CN_option$sockopt"
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
tcmd="$tcmd stdio" tcmd="$tcmd stdio"
fi fi
...@@ -473,6 +492,12 @@ check_server_ssl_config() ...@@ -473,6 +492,12 @@ check_server_ssl_config()
"of the tca, tcert and/or tkey in the [sst] section" "of the tca, tcert and/or tkey in the [sst] section"
fi fi
fi fi
if [ -n "$tcert" ]; then
tcert=$(trim_string "$tcert")
if [ "${tcert%/}" != "$tcert" ]; then
tpath=1
fi
fi
} }
read_cnf() read_cnf()
......
...@@ -236,11 +236,18 @@ check_server_ssl_config() ...@@ -236,11 +236,18 @@ check_server_ssl_config()
SSLMODE=$(parse_cnf "$SST_SECTIONS" 'ssl-mode' | tr [:lower:] [:upper:]) SSLMODE=$(parse_cnf "$SST_SECTIONS" 'ssl-mode' | tr [:lower:] [:upper:])
# no old-style SSL config in [sst], check for new one: # no old-style SSL config in [sst], check for new one:
if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ] if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]; then
then
check_server_ssl_config check_server_ssl_config
fi fi
SSTPATH=0
if [ -n "$SSTCA" ]; then
SSTCA=$(trim_string "$SSTCA")
if [ "${SSTCA%/}" != "$SSTCA" ]; then
SSTPATH=1
fi
fi
if [ -z "$SSLMODE" ]; then if [ -z "$SSLMODE" ]; then
# Implicit verification if CA is set and the SSL mode # Implicit verification if CA is set and the SSL mode
# is not specified by user: # is not specified by user:
...@@ -254,9 +261,19 @@ if [ -z "$SSLMODE" ]; then ...@@ -254,9 +261,19 @@ if [ -z "$SSLMODE" ]; then
fi fi
fi fi
if [ -n "$SSTCA" ] if [ -n "$SSTCERT" -a -n "$SSTKEY" ]; then
then verify_cert_matches_key "$SSTCERT" "$SSTKEY"
CAFILE_OPT="CAfile = $SSTCA" fi
if [ -n "$SSTCA" ]; then
if [ $SSTPATH -eq 0 ]; then
CAFILE_OPT="CAfile = $SSTCA"
else
CAFILE_OPT="CApath = $SSTCA"
fi
if [ -n "$SSTCERT" ]; then
verify_ca_matches_cert "$SSTCA" "$SSTCERT" $SSTPATH
fi
else else
CAFILE_OPT="" CAFILE_OPT=""
fi fi
...@@ -272,38 +289,38 @@ then ...@@ -272,38 +289,38 @@ then
;; ;;
'VERIFY_CA') 'VERIFY_CA')
VERIFY_OPT='verifyChain = yes' VERIFY_OPT='verifyChain = yes'
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
CHECK_OPT="checkHost = $WSREP_SST_OPT_REMOTE_USER"
else
# check if the address is an ip-address (v4 or v6):
if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \
grep -q -E '^([0-9]+(\.[0-9]+){3}|[0-9a-fA-F]*(\:[0-9a-fA-F]*)+)$'
then
CHECK_OPT="checkIP = $WSREP_SST_OPT_HOST_UNESCAPED"
else
CHECK_OPT="checkHost = $WSREP_SST_OPT_HOST"
fi
if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
CHECK_OPT_LOCAL="checkHost = localhost"
fi
fi
;; ;;
*) *)
wsrep_log_error "Unrecognized ssl-mode option: '$SSLMODE'" wsrep_log_error "Unrecognized ssl-mode option: '$SSLMODE'"
exit 22 # EINVAL exit 22 # EINVAL
;; ;;
esac esac
if [ -z "$CAFILE_OPT" ]; then if [ -z "$SSTCA" ]; then
wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file" wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file or path"
exit 22 # EINVAL exit 22 # EINVAL
fi fi
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
CHECK_OPT="checkHost = $WSREP_SST_OPT_REMOTE_USER"
elif [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then
# check if the address is an ip-address (v4 or v6):
if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \
grep -q -E '^([0-9]+(\.[0-9]+){3}|[0-9a-fA-F]*(\:[0-9a-fA-F]*)+)$'
then
CHECK_OPT="checkIP = $WSREP_SST_OPT_HOST_UNESCAPED"
else
CHECK_OPT="checkHost = $WSREP_SST_OPT_HOST"
fi
if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
CHECK_OPT_LOCAL="checkHost = localhost"
fi
fi
fi fi
STUNNEL="" STUNNEL=""
if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ]; then if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ]; then
STUNNEL_BIN="$(command -v stunnel)" STUNNEL_BIN="$(command -v stunnel)"
if [ -n "$STUNNEL_BIN" ]; then if [ -n "$STUNNEL_BIN" ]; then
wsrep_log_info "Using stunnel for SSL encryption: CAfile: '$SSTCA', ssl-mode='$SSLMODE'" wsrep_log_info "Using stunnel for SSL encryption: CA: '$SSTCA', ssl-mode='$SSLMODE'"
STUNNEL="$STUNNEL_BIN $STUNNEL_CONF" STUNNEL="$STUNNEL_BIN $STUNNEL_CONF"
fi fi
fi fi
......
...@@ -6167,8 +6167,8 @@ wsrep_innobase_mysql_sort( ...@@ -6167,8 +6167,8 @@ wsrep_innobase_mysql_sort(
case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VARCHAR:
{ {
uchar *tmp_str; uchar tmp_str[REC_VERSION_56_MAX_INDEX_COL_LEN] = {'\0'};
ulint tmp_length; ulint tmp_length = REC_VERSION_56_MAX_INDEX_COL_LEN;
/* Use the charset number to pick the right charset struct for /* Use the charset number to pick the right charset struct for
the comparison. Since the MySQL function get_charset may be the comparison. Since the MySQL function get_charset may be
...@@ -6191,12 +6191,7 @@ wsrep_innobase_mysql_sort( ...@@ -6191,12 +6191,7 @@ wsrep_innobase_mysql_sort(
} }
} }
// Note that strnxfrm may change length of string ut_a(str_length <= tmp_length);
tmp_length= charset->coll->strnxfrmlen(charset, str_length);
tmp_length= tmp_length * charset->mbmaxlen;
tmp_length= ut_max(str_length, tmp_length) + charset->mbmaxlen;
tmp_str= static_cast<uchar *>(ut_malloc_nokey(tmp_length));
ut_ad(str_length <= tmp_length);
memcpy(tmp_str, str, str_length); memcpy(tmp_str, str, str_length);
tmp_length = charset->strnxfrm(str, str_length, tmp_length = charset->strnxfrm(str, str_length,
...@@ -6220,7 +6215,6 @@ wsrep_innobase_mysql_sort( ...@@ -6220,7 +6215,6 @@ wsrep_innobase_mysql_sort(
ret_length = tmp_length; ret_length = tmp_length;
} }
ut_free(tmp_str);
break; break;
} }
case MYSQL_TYPE_DECIMAL : case MYSQL_TYPE_DECIMAL :
...@@ -6566,7 +6560,7 @@ wsrep_store_key_val_for_row( ...@@ -6566,7 +6560,7 @@ wsrep_store_key_val_for_row(
THD* thd, THD* thd,
TABLE* table, TABLE* table,
uint keynr, /*!< in: key number */ uint keynr, /*!< in: key number */
uchar* buff, /*!< in/out: buffer for the key value (in MySQL char* buff, /*!< in/out: buffer for the key value (in MySQL
format) */ format) */
uint buff_len,/*!< in: buffer length */ uint buff_len,/*!< in: buffer length */
const uchar* record, const uchar* record,
...@@ -6575,7 +6569,7 @@ wsrep_store_key_val_for_row( ...@@ -6575,7 +6569,7 @@ wsrep_store_key_val_for_row(
KEY* key_info = table->key_info + keynr; KEY* key_info = table->key_info + keynr;
KEY_PART_INFO* key_part = key_info->key_part; KEY_PART_INFO* key_part = key_info->key_part;
KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts; KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts;
uchar* buff_start = buff; char* buff_start = buff;
enum_field_types mysql_type; enum_field_types mysql_type;
Field* field; Field* field;
ulint buff_space = buff_len; ulint buff_space = buff_len;
...@@ -6586,7 +6580,7 @@ wsrep_store_key_val_for_row( ...@@ -6586,7 +6580,7 @@ wsrep_store_key_val_for_row(
*key_is_null = true; *key_is_null = true;
for (; key_part != end; key_part++) { for (; key_part != end; key_part++) {
uchar *sorted = nullptr; uchar sorted[REC_VERSION_56_MAX_INDEX_COL_LEN] = {'\0'};
bool part_is_null = false; bool part_is_null = false;
if (key_part->null_bit) { if (key_part->null_bit) {
...@@ -6665,14 +6659,10 @@ wsrep_store_key_val_for_row( ...@@ -6665,14 +6659,10 @@ wsrep_store_key_val_for_row(
true_len = key_len; true_len = key_len;
} }
const ulint max_len = true_len;
sorted= static_cast<uchar *>(ut_malloc_nokey(max_len+1));
memcpy(sorted, data, true_len); memcpy(sorted, data, true_len);
true_len = wsrep_innobase_mysql_sort( true_len = wsrep_innobase_mysql_sort(
mysql_type, cs->number, sorted, true_len, mysql_type, cs->number, sorted, true_len,
max_len); REC_VERSION_56_MAX_INDEX_COL_LEN);
ut_ad(true_len <= max_len);
if (wsrep_protocol_version > 1) { if (wsrep_protocol_version > 1) {
/* Note that we always reserve the maximum possible /* Note that we always reserve the maximum possible
length of the true VARCHAR in the key value, though length of the true VARCHAR in the key value, though
...@@ -6757,13 +6747,11 @@ wsrep_store_key_val_for_row( ...@@ -6757,13 +6747,11 @@ wsrep_store_key_val_for_row(
true_len = key_len; true_len = key_len;
} }
const ulint max_len= true_len;
sorted= static_cast<uchar *>(ut_malloc_nokey(max_len+1));
memcpy(sorted, blob_data, true_len); memcpy(sorted, blob_data, true_len);
true_len = wsrep_innobase_mysql_sort( true_len = wsrep_innobase_mysql_sort(
mysql_type, cs->number, sorted, true_len, mysql_type, cs->number, sorted, true_len,
max_len); REC_VERSION_56_MAX_INDEX_COL_LEN);
ut_ad(true_len <= max_len);
/* Note that we always reserve the maximum possible /* Note that we always reserve the maximum possible
length of the BLOB prefix in the key value. */ length of the BLOB prefix in the key value. */
...@@ -6839,14 +6827,10 @@ wsrep_store_key_val_for_row( ...@@ -6839,14 +6827,10 @@ wsrep_store_key_val_for_row(
cs->mbmaxlen), cs->mbmaxlen),
&error); &error);
} }
const ulint max_len = true_len;
sorted= static_cast<uchar *>(ut_malloc_nokey(max_len+1));
memcpy(sorted, src_start, true_len); memcpy(sorted, src_start, true_len);
true_len = wsrep_innobase_mysql_sort( true_len = wsrep_innobase_mysql_sort(
mysql_type, cs->number, sorted, true_len, mysql_type, cs->number, sorted, true_len,
max_len); REC_VERSION_56_MAX_INDEX_COL_LEN);
ut_ad(true_len <= max_len);
if (true_len > buff_space) { if (true_len > buff_space) {
fprintf (stderr, fprintf (stderr,
...@@ -6861,11 +6845,6 @@ wsrep_store_key_val_for_row( ...@@ -6861,11 +6845,6 @@ wsrep_store_key_val_for_row(
buff += true_len; buff += true_len;
buff_space -= true_len; buff_space -= true_len;
} }
if (sorted) {
ut_free(sorted);
sorted= NULL;
}
} }
ut_a(buff <= buff_start + buff_len); ut_a(buff <= buff_start + buff_len);
...@@ -9890,7 +9869,7 @@ wsrep_append_key( ...@@ -9890,7 +9869,7 @@ wsrep_append_key(
THD *thd, THD *thd,
trx_t *trx, trx_t *trx,
TABLE_SHARE *table_share, TABLE_SHARE *table_share,
const uchar* key, const char* key,
uint16_t key_len, uint16_t key_len,
Wsrep_service_key_type key_type /*!< in: access type of this key Wsrep_service_key_type key_type /*!< in: access type of this key
(shared, exclusive, semi...) */ (shared, exclusive, semi...) */
...@@ -10001,8 +9980,8 @@ ha_innobase::wsrep_append_keys( ...@@ -10001,8 +9980,8 @@ ha_innobase::wsrep_append_keys(
} }
if (wsrep_protocol_version == 0) { if (wsrep_protocol_version == 0) {
uchar keyval[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; char keyval[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'};
uchar *key = &keyval[0]; char *key = &keyval[0];
bool is_null; bool is_null;
auto len = wsrep_store_key_val_for_row( auto len = wsrep_store_key_val_for_row(
...@@ -10043,12 +10022,12 @@ ha_innobase::wsrep_append_keys( ...@@ -10043,12 +10022,12 @@ ha_innobase::wsrep_append_keys(
/* keyval[] shall contain an ordinal number at byte 0 /* keyval[] shall contain an ordinal number at byte 0
and the actual key data shall be written at byte 1. and the actual key data shall be written at byte 1.
Hence the total data length is the key length + 1 */ Hence the total data length is the key length + 1 */
uchar keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]= {'\0'}; char keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]= {'\0'};
uchar keyval1[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]= {'\0'}; char keyval1[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]= {'\0'};
keyval0[0] = (uchar)i; keyval0[0] = (char)i;
keyval1[0] = (uchar)i; keyval1[0] = (char)i;
uchar* key0 = &keyval0[1]; char* key0 = &keyval0[1];
uchar* key1 = &keyval1[1]; char* key1 = &keyval1[1];
if (!tab) { if (!tab) {
WSREP_WARN("MariaDB-InnoDB key mismatch %s %s", WSREP_WARN("MariaDB-InnoDB key mismatch %s %s",
...@@ -10128,16 +10107,18 @@ ha_innobase::wsrep_append_keys( ...@@ -10128,16 +10107,18 @@ ha_innobase::wsrep_append_keys(
wsrep_calc_row_hash(digest, record0, table, m_prebuilt); wsrep_calc_row_hash(digest, record0, table, m_prebuilt);
if (int rcode = wsrep_append_key(thd, trx, table_share, if (int rcode = wsrep_append_key(thd, trx, table_share,
digest, 16, key_type)) { reinterpret_cast<char*>
(digest), 16, key_type)) {
DBUG_RETURN(rcode); DBUG_RETURN(rcode);
} }
if (record1) { if (record1) {
wsrep_calc_row_hash( wsrep_calc_row_hash(
digest, record1, table, m_prebuilt); digest, record1, table, m_prebuilt);
if (int rcode = wsrep_append_key(thd, trx, table_share, if (int rcode = wsrep_append_key(
digest, 16, thd, trx, table_share,
key_type)) { reinterpret_cast<char*>(digest), 16,
key_type)) {
DBUG_RETURN(rcode); DBUG_RETURN(rcode);
} }
} }
......
...@@ -91,16 +91,15 @@ datadir_set= ...@@ -91,16 +91,15 @@ datadir_set=
# #
# Use LSB init script functions for printing messages, if possible # Use LSB init script functions for printing messages, if possible
# # Include non-LSB RedHat init functions to make systemctl redirect work
init_functions="/etc/init.d/functions"
lsb_functions="/lib/lsb/init-functions" lsb_functions="/lib/lsb/init-functions"
if test -f $lsb_functions ; then if test -f $lsb_functions; then
. $lsb_functions . $lsb_functions
else fi
# Include non-LSB RedHat init functions to make systemctl redirect work
init_functions="/etc/init.d/functions" if test -f $init_functions; then
if test -f $init_functions; then . $init_functions
. $init_functions
fi
log_success_msg() log_success_msg()
{ {
echo " SUCCESS! $@" echo " SUCCESS! $@"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment