Merge branch '2.2' into develop
This commit is contained in:
@ -18,7 +18,7 @@ cd build
|
|||||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=Y
|
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=Y
|
||||||
|
|
||||||
make
|
make
|
||||||
make test || exit 1
|
ctest --output-on-failure || exit 1
|
||||||
|
|
||||||
sudo make install
|
sudo make install
|
||||||
sudo ./postinst
|
sudo ./postinst
|
||||||
|
@ -16,6 +16,8 @@ make
|
|||||||
|
|
||||||
if [[ "$cmake_flags" =~ "BUILD_TESTS" ]]
|
if [[ "$cmake_flags" =~ "BUILD_TESTS" ]]
|
||||||
then
|
then
|
||||||
|
# We don't care about memory leaks in the tests (e.g. servers are never freed)
|
||||||
|
export ASAN_OPTIONS=detect_leaks=0
|
||||||
# All tests must pass otherwise the build is considered a failure
|
# All tests must pass otherwise the build is considered a failure
|
||||||
ctest --output-on-failure || exit 1
|
ctest --output-on-failure || exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -12,29 +12,32 @@ _GSSAPIBackendAuth_ module implements the backend authentication.
|
|||||||
For Unix systems, the usual GSSAPI implementation is Kerberos. This is a short
|
For Unix systems, the usual GSSAPI implementation is Kerberos. This is a short
|
||||||
guide on how to set up Kerberos for MaxScale.
|
guide on how to set up Kerberos for MaxScale.
|
||||||
|
|
||||||
The first step is to create a new principal for MaxScale. This can be done with
|
The first step is to configure MariaDB to use GSSAPI authentication. The MariaDB
|
||||||
the _kadmin_ or _kadmin.local_ tools.
|
documentation for the
|
||||||
|
[GSSAPI Authentication Plugin](https://mariadb.com/kb/en/mariadb/gssapi-authentication-plugin/)
|
||||||
|
is a good example on how to set it up.
|
||||||
|
|
||||||
|
The next step is to copy the keytab file from the server where MariaDB is
|
||||||
|
installed to the server where MaxScale is located. The keytab file must be
|
||||||
|
placed in the configured default location which almost always is
|
||||||
|
`/etc/krb5.keytab`.
|
||||||
|
|
||||||
|
To take GSSAPI authentication into use, add the following to the listener.
|
||||||
|
|
||||||
```
|
```
|
||||||
kadmin.local -q "addprinc -nokey mariadb/example.com@EXAMPLE.COM"
|
authenticator=GSSAPIAuth
|
||||||
|
authenticator_options=principal_name=mariadb/localhost.localdomain@EXAMPLE.COM
|
||||||
```
|
```
|
||||||
|
|
||||||
The `-nokey` option will make the principal a passwordless one. This allows the
|
Change the principal name to the same value you configured for the MariaDB
|
||||||
_maxscale_ user to acquire a ticket for it without a password being prompted.
|
server.
|
||||||
|
|
||||||
The next step is to export this principal into the Kerberos keytab file.
|
After the listeners are configured, add the following to all servers that use GSSAPI users.
|
||||||
|
|
||||||
```
|
```
|
||||||
kadmin.local -q "ktadd -k /etc/krb5.keytab -norandkey mariadb/example.com@EXAMPLE.COM"
|
authenticator=GSSAPIBackendAuth
|
||||||
```
|
```
|
||||||
|
|
||||||
This adds the _mariadb/example.com@EXAMPLE.COM_ principal into the keytab
|
|
||||||
file. The `-norandkey` option tells that the password we defined earlier,
|
|
||||||
i.e. no password at all, should be used instead of a random password.
|
|
||||||
|
|
||||||
The MariaDB documentation for the [GSSAPI Authentication Plugin](https://mariadb.com/kb/en/mariadb/gssapi-authentication-plugin/)
|
|
||||||
is a good example on how to set up a new principal for the MariaDB server.
|
|
||||||
|
|
||||||
## Authenticator options
|
## Authenticator options
|
||||||
|
|
||||||
The client side GSSAPIAuth authenticator supports one option, the service
|
The client side GSSAPIAuth authenticator supports one option, the service
|
||||||
@ -43,14 +46,12 @@ module has no options.
|
|||||||
|
|
||||||
### `principal_name`
|
### `principal_name`
|
||||||
|
|
||||||
The service principal name to send to the client. This parameter is a
|
The service principal name to send to the client. This parameter is a string
|
||||||
string parameter which is used by the client to request the token.
|
parameter which is used by the client to request the token. The default value
|
||||||
|
for this option is _mariadb/localhost.localdomain_.
|
||||||
|
|
||||||
The default value for this option is _mariadb/localhost.localdomain_.
|
This parameter *must* be the same as the principal name that the backend MariaDB
|
||||||
|
server uses.
|
||||||
The parameter must be a valid GSSAPI principal name
|
|
||||||
e.g. `styx/pluto@EXAMPLE.COM`. The principal name can also be defined
|
|
||||||
without the realm part in which case the default realm will be used.
|
|
||||||
|
|
||||||
## Implementation details
|
## Implementation details
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
set(MAXSCALE_VERSION_MAJOR "2" CACHE STRING "Major version")
|
set(MAXSCALE_VERSION_MAJOR "2" CACHE STRING "Major version")
|
||||||
set(MAXSCALE_VERSION_MINOR "2" CACHE STRING "Minor version")
|
set(MAXSCALE_VERSION_MINOR "2" CACHE STRING "Minor version")
|
||||||
set(MAXSCALE_VERSION_PATCH "15" CACHE STRING "Patch version")
|
set(MAXSCALE_VERSION_PATCH "16" CACHE STRING "Patch version")
|
||||||
|
|
||||||
# This should only be incremented if a package is rebuilt
|
# This should only be incremented if a package is rebuilt
|
||||||
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
||||||
|
@ -24,32 +24,18 @@ MXS_BEGIN_DECLS
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MXS_BACKEND_SO_RCVBUF
|
* MXS_SO_RCVBUF
|
||||||
*
|
*
|
||||||
* The value used when setting SO_RCVBUF of backend sockets.
|
* The size of the network input buffer.
|
||||||
*/
|
*/
|
||||||
#define MXS_BACKEND_SO_RCVBUF (128 * 1024)
|
#define MXS_SO_RCVBUF_SIZE (128 * 1024)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MXS_BACKEND_SO_SNDBUF
|
* MXS_SO_SNDBUF
|
||||||
*
|
*
|
||||||
* The value used when setting SO_SNDBUF of backend sockets.
|
* The size of the network output buffer.
|
||||||
*/
|
*/
|
||||||
#define MXS_BACKEND_SO_SNDBUF (128 * 1024)
|
#define MXS_SO_SNDBUF_SIZE (128 * 1024)
|
||||||
|
|
||||||
/**
|
|
||||||
* MXS_CLIENT_SO_RCVBUF
|
|
||||||
*
|
|
||||||
* The value used when setting SO_RCVBUF of client sockets.
|
|
||||||
*/
|
|
||||||
#define MXS_CLIENT_SO_RCVBUF (128 * 1024)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MXS_CLIENT_SO_SNDBUF
|
|
||||||
*
|
|
||||||
* The value used when setting SO_SNDBUF of client sockets.
|
|
||||||
*/
|
|
||||||
#define MXS_CLIENT_SO_SNDBUF (128 * 1024)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MXS_MAX_NW_READ_BUFFER_SIZE
|
* MXS_MAX_NW_READ_BUFFER_SIZE
|
||||||
|
@ -46,6 +46,20 @@ enum mxs_socket_type
|
|||||||
bool utils_init(); /*< Call this first before using any other function */
|
bool utils_init(); /*< Call this first before using any other function */
|
||||||
void utils_end();
|
void utils_end();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure network socket options
|
||||||
|
*
|
||||||
|
* This is a helper function for setting various socket options that are always wanted for all types
|
||||||
|
* of connections. It sets the socket into nonblocking mode, configures sndbuf and rcvbuf sizes
|
||||||
|
* and sets TCP_NODELAY (no Nagle algorithm).
|
||||||
|
*
|
||||||
|
* @param so Socket to configure
|
||||||
|
* @param type Socket type
|
||||||
|
*
|
||||||
|
* @return True if configuration was successful
|
||||||
|
*/
|
||||||
|
bool configure_network_socket(int so, int type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a network socket and a socket configuration
|
* @brief Create a network socket and a socket configuration
|
||||||
*
|
*
|
||||||
|
@ -23,7 +23,7 @@ void get_output(TestConnections& test)
|
|||||||
test.tprintf("MaxScale output:");
|
test.tprintf("MaxScale output:");
|
||||||
}
|
}
|
||||||
output = test.maxscales->ssh_node_output(0,
|
output = test.maxscales->ssh_node_output(0,
|
||||||
"cat /var/log/maxscale/maxscale.log && "
|
"cat /var/log/maxscale/maxscale.log | tee -a /var/log/maxscale/maxscale_backup.log && "
|
||||||
"sudo truncate -s 0 /var/log/maxscale/maxscale.log",
|
"sudo truncate -s 0 /var/log/maxscale/maxscale.log",
|
||||||
true,
|
true,
|
||||||
&ec);
|
&ec);
|
||||||
|
@ -23,6 +23,7 @@ export node_N=`cat "$MDBCI_VM_PATH/$config_name"_network_config | grep node | gr
|
|||||||
export maxscale_N=`cat "$MDBCI_VM_PATH/$config_name"_network_config | grep maxscale | grep network | wc -l`
|
export maxscale_N=`cat "$MDBCI_VM_PATH/$config_name"_network_config | grep maxscale | grep network | wc -l`
|
||||||
sed "s/^/export /g" "$MDBCI_VM_PATH/$config_name"_network_config > "$curr_dir"/"$config_name"_network_config_export
|
sed "s/^/export /g" "$MDBCI_VM_PATH/$config_name"_network_config > "$curr_dir"/"$config_name"_network_config_export
|
||||||
source "$curr_dir"/"$config_name"_network_config_export
|
source "$curr_dir"/"$config_name"_network_config_export
|
||||||
|
rm "$curr_dir"/"$config_name"_network_config_export
|
||||||
|
|
||||||
|
|
||||||
# User name and Password for Master/Slave replication setup (should have all PRIVILEGES)
|
# User name and Password for Master/Slave replication setup (should have all PRIVILEGES)
|
||||||
|
@ -45,8 +45,9 @@ int main(int argc, char** argv)
|
|||||||
test.try_query(test.repl->nodes[0], "%s", "GRANT ALL ON *.* TO 'mxs1743'@'%'");
|
test.try_query(test.repl->nodes[0], "%s", "GRANT ALL ON *.* TO 'mxs1743'@'%'");
|
||||||
|
|
||||||
test.tprintf("Syncing slaves");
|
test.tprintf("Syncing slaves");
|
||||||
test.set_timeout(60);
|
test.stop_timeout();
|
||||||
test.repl->sync_slaves();
|
test.repl->sync_slaves();
|
||||||
|
test.set_timeout(60);
|
||||||
|
|
||||||
test.tprintf("Opening new connections to verify readconnroute works");
|
test.tprintf("Opening new connections to verify readconnroute works");
|
||||||
|
|
||||||
|
@ -35,16 +35,21 @@ int main(int argc, char* argv[])
|
|||||||
test.stop_timeout();
|
test.stop_timeout();
|
||||||
test.repl->connect();
|
test.repl->connect();
|
||||||
test.repl->sync_slaves();
|
test.repl->sync_slaves();
|
||||||
|
test.repl->disconnect();
|
||||||
|
|
||||||
test.set_timeout(60);
|
test.set_timeout(60);
|
||||||
|
test.maxscales->connect();
|
||||||
check_val(test.maxscales->conn_rwsplit[0], test);
|
check_val(test.maxscales->conn_rwsplit[0], test);
|
||||||
check_val(test.maxscales->conn_master[0], test);
|
check_val(test.maxscales->conn_master[0], test);
|
||||||
check_val(test.maxscales->conn_slave[0], test);
|
check_val(test.maxscales->conn_slave[0], test);
|
||||||
|
test.maxscales->disconnect();
|
||||||
|
|
||||||
|
nodes->connect();
|
||||||
for (int i = 0; i < test.repl->N; i++)
|
for (int i = 0; i < test.repl->N; i++)
|
||||||
{
|
{
|
||||||
check_val(nodes->nodes[i], test);
|
check_val(nodes->nodes[i], test);
|
||||||
}
|
}
|
||||||
|
nodes->disconnect();
|
||||||
|
|
||||||
return test.global_result;
|
return test.global_result;
|
||||||
}
|
}
|
||||||
|
@ -226,6 +226,13 @@ void mxb_log_set_throttling(const MXB_LOG_THROTTLING* throttling);
|
|||||||
*/
|
*/
|
||||||
void mxb_log_get_throttling(MXB_LOG_THROTTLING* throttling);
|
void mxb_log_get_throttling(MXB_LOG_THROTTLING* throttling);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect stdout to the log file
|
||||||
|
*
|
||||||
|
* @param redirect Whether to redirect the output to the log file
|
||||||
|
*/
|
||||||
|
void mxs_log_redirect_stdout(bool redirect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log a message of a particular priority.
|
* Log a message of a particular priority.
|
||||||
*
|
*
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstdio>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@ -384,6 +385,7 @@ struct this_unit
|
|||||||
bool do_highprecision; // Can change during the lifetime of log_manager.
|
bool do_highprecision; // Can change during the lifetime of log_manager.
|
||||||
bool do_syslog; // Can change during the lifetime of log_manager.
|
bool do_syslog; // Can change during the lifetime of log_manager.
|
||||||
bool do_maxlog; // Can change during the lifetime of log_manager.
|
bool do_maxlog; // Can change during the lifetime of log_manager.
|
||||||
|
bool redirect_stdout;
|
||||||
MXB_LOG_THROTTLING throttling; // Can change during the lifetime of log_manager.
|
MXB_LOG_THROTTLING throttling; // Can change during the lifetime of log_manager.
|
||||||
std::unique_ptr<mxb::Logger> sLogger;
|
std::unique_ptr<mxb::Logger> sLogger;
|
||||||
std::unique_ptr<MessageRegistry> sMessage_registry;
|
std::unique_ptr<MessageRegistry> sMessage_registry;
|
||||||
@ -394,6 +396,7 @@ struct this_unit
|
|||||||
false, // do_highprecision
|
false, // do_highprecision
|
||||||
true, // do_syslog
|
true, // do_syslog
|
||||||
true, // do_maxlog
|
true, // do_maxlog
|
||||||
|
false, // redirect_stdout
|
||||||
DEFAULT_LOG_THROTTLING, // throttling
|
DEFAULT_LOG_THROTTLING, // throttling
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -486,6 +489,13 @@ bool mxb_log_init(const char* ident,
|
|||||||
case MXB_LOG_TARGET_FS:
|
case MXB_LOG_TARGET_FS:
|
||||||
case MXB_LOG_TARGET_DEFAULT:
|
case MXB_LOG_TARGET_DEFAULT:
|
||||||
this_unit.sLogger = mxb::FileLogger::create(filepath);
|
this_unit.sLogger = mxb::FileLogger::create(filepath);
|
||||||
|
|
||||||
|
if (this_unit.sLogger && this_unit.redirect_stdout)
|
||||||
|
{
|
||||||
|
// Redirect stdout and stderr to the log file
|
||||||
|
freopen(this_unit.sLogger->filename(), "a", stdout);
|
||||||
|
freopen(this_unit.sLogger->filename(), "a", stderr);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MXB_LOG_TARGET_STDOUT:
|
case MXB_LOG_TARGET_STDOUT:
|
||||||
@ -598,9 +608,23 @@ void mxb_log_get_throttling(MXB_LOG_THROTTLING* throttling)
|
|||||||
*throttling = this_unit.throttling;
|
*throttling = this_unit.throttling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mxs_log_redirect_stdout(bool redirect)
|
||||||
|
{
|
||||||
|
this_unit.redirect_stdout = redirect;
|
||||||
|
}
|
||||||
|
|
||||||
bool mxb_log_rotate()
|
bool mxb_log_rotate()
|
||||||
{
|
{
|
||||||
return this_unit.sLogger->rotate();
|
bool rval = this_unit.sLogger->rotate();
|
||||||
|
|
||||||
|
if (this_unit.redirect_stdout && rval)
|
||||||
|
{
|
||||||
|
// Redirect stdout and stderr to the log file
|
||||||
|
freopen(this_unit.sLogger->filename(), "a", stdout);
|
||||||
|
freopen(this_unit.sLogger->filename(), "a", stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* mxb_log_get_filename()
|
const char* mxb_log_get_filename()
|
||||||
|
@ -2405,21 +2405,7 @@ DCB* dcb_accept(DCB* dcb)
|
|||||||
{
|
{
|
||||||
dcb->stats.n_accepts++;
|
dcb->stats.n_accepts++;
|
||||||
|
|
||||||
/* set nonblocking */
|
configure_network_socket(c_sock, client_conn.ss_family);
|
||||||
sendbuf = MXS_CLIENT_SO_SNDBUF;
|
|
||||||
|
|
||||||
if (setsockopt(c_sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, optlen) != 0)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Failed to set socket options: %d, %s", errno, mxs_strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
sendbuf = MXS_CLIENT_SO_RCVBUF;
|
|
||||||
|
|
||||||
if (setsockopt(c_sock, SOL_SOCKET, SO_RCVBUF, &sendbuf, optlen) != 0)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Failed to set socket options: %d, %s", errno, mxs_strerror(errno));
|
|
||||||
}
|
|
||||||
setnonblocking(c_sock);
|
|
||||||
|
|
||||||
client_dcb = dcb_alloc(DCB_ROLE_CLIENT_HANDLER, dcb->listener);
|
client_dcb = dcb_alloc(DCB_ROLE_CLIENT_HANDLER, dcb->listener);
|
||||||
|
|
||||||
|
@ -347,12 +347,15 @@ static void sigterm_handler(int i)
|
|||||||
int n_shutdowns = maxscale_shutdown();
|
int n_shutdowns = maxscale_shutdown();
|
||||||
|
|
||||||
if (n_shutdowns == 1)
|
if (n_shutdowns == 1)
|
||||||
|
{
|
||||||
|
if (!daemon_mode)
|
||||||
{
|
{
|
||||||
if (write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1) == -1)
|
if (write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1) == -1)
|
||||||
{
|
{
|
||||||
printf("Failed to write shutdown message!\n");
|
printf("Failed to write shutdown message!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@ -365,19 +368,25 @@ static void sigint_handler(int i)
|
|||||||
int n_shutdowns = maxscale_shutdown();
|
int n_shutdowns = maxscale_shutdown();
|
||||||
|
|
||||||
if (n_shutdowns == 1)
|
if (n_shutdowns == 1)
|
||||||
|
{
|
||||||
|
if (!daemon_mode)
|
||||||
{
|
{
|
||||||
if (write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1) == -1)
|
if (write(STDERR_FILENO, shutdown_msg, sizeof(shutdown_msg) - 1) == -1)
|
||||||
{
|
{
|
||||||
printf("Failed to write shutdown message!\n");
|
printf("Failed to write shutdown message!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (n_shutdowns == 2)
|
else if (n_shutdowns == 2)
|
||||||
|
{
|
||||||
|
if (!daemon_mode)
|
||||||
{
|
{
|
||||||
if (write(STDERR_FILENO, patience_msg, sizeof(patience_msg) - 1) == -1)
|
if (write(STDERR_FILENO, patience_msg, sizeof(patience_msg) - 1) == -1)
|
||||||
{
|
{
|
||||||
printf("Failed to write shutdown message!\n");
|
printf("Failed to write shutdown message!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
@ -1919,6 +1928,11 @@ int main(int argc, char** argv)
|
|||||||
mxs_log_finish();
|
mxs_log_finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cnf->log_target != MXB_LOG_TARGET_STDOUT && daemon_mode)
|
||||||
|
{
|
||||||
|
mxs_log_redirect_stdout(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (!init_log())
|
if (!init_log())
|
||||||
{
|
{
|
||||||
rc = MAXSCALE_BADCONFIG;
|
rc = MAXSCALE_BADCONFIG;
|
||||||
|
@ -983,17 +983,18 @@ void utils_end()
|
|||||||
replace_values_re = NULL;
|
replace_values_re = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool configure_network_socket(int so)
|
bool configure_network_socket(int so, int type)
|
||||||
{
|
{
|
||||||
int sndbufsize = MXS_BACKEND_SO_SNDBUF;
|
int sndbufsize = MXS_SO_SNDBUF_SIZE;
|
||||||
int rcvbufsize = MXS_BACKEND_SO_RCVBUF;
|
int rcvbufsize = MXS_SO_RCVBUF_SIZE;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
|
|
||||||
if (setsockopt(so, SOL_SOCKET, SO_SNDBUF, &sndbufsize, sizeof(sndbufsize)) != 0
|
if (setsockopt(so, SOL_SOCKET, SO_SNDBUF, &sndbufsize, sizeof(sndbufsize)) != 0
|
||||||
|| setsockopt(so, SOL_SOCKET, SO_RCVBUF, &rcvbufsize, sizeof(rcvbufsize)) != 0
|
|| setsockopt(so, SOL_SOCKET, SO_RCVBUF, &rcvbufsize, sizeof(rcvbufsize)) != 0
|
||||||
|| setsockopt(so, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) != 0)
|
|| (type != AF_UNIX && setsockopt(so, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) != 0))
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to set socket option: %d, %s.", errno, mxs_strerror(errno));
|
MXS_ERROR("Failed to set socket option: %d, %s.", errno, mxs_strerror(errno));
|
||||||
|
mxb_assert(!true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1065,7 +1066,7 @@ int open_network_socket(enum mxs_socket_type type,
|
|||||||
|
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
|
|
||||||
if ((type == MXS_SOCKET_NETWORK && !configure_network_socket(so))
|
if ((type == MXS_SOCKET_NETWORK && !configure_network_socket(so, addr->ss_family))
|
||||||
|| (type == MXS_SOCKET_LISTENER && !configure_listener_socket(so)))
|
|| (type == MXS_SOCKET_LISTENER && !configure_listener_socket(so)))
|
||||||
{
|
{
|
||||||
close(so);
|
close(so);
|
||||||
|
@ -59,56 +59,19 @@ void gssapi_backend_auth_free(void* data)
|
|||||||
static bool send_new_auth_token(DCB* dcb)
|
static bool send_new_auth_token(DCB* dcb)
|
||||||
{
|
{
|
||||||
bool rval = false;
|
bool rval = false;
|
||||||
OM_uint32 major = 0, minor = 0;
|
|
||||||
gss_ctx_id_t handle = NULL;
|
|
||||||
gss_buffer_desc in = {0, 0};
|
|
||||||
gss_buffer_desc out = {0, 0};
|
|
||||||
gss_buffer_desc target = {0, 0};
|
|
||||||
gss_name_t princ = GSS_C_NO_NAME;
|
|
||||||
gssapi_auth_t* auth = (gssapi_auth_t*)dcb->authenticator_data;
|
gssapi_auth_t* auth = (gssapi_auth_t*)dcb->authenticator_data;
|
||||||
|
MYSQL_session* ses = (MYSQL_session*)dcb->session->client_dcb->data;
|
||||||
|
GWBUF* buffer = gwbuf_alloc(MYSQL_HEADER_LEN + ses->auth_token_len);
|
||||||
|
|
||||||
/** The service principal name is sent by the backend server */
|
// This function actually just forwards the client's token to the backend server
|
||||||
target.value = auth->principal_name;
|
|
||||||
target.length = auth->principal_name_len + 1;
|
|
||||||
|
|
||||||
/** Convert the name into GSSAPI format */
|
|
||||||
major = gss_import_name(&minor, &target, GSS_C_NT_USER_NAME, &princ);
|
|
||||||
|
|
||||||
if (GSS_ERROR(major))
|
|
||||||
{
|
|
||||||
report_error(major, minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Request the token for the service */
|
|
||||||
major = gss_init_sec_context(&minor,
|
|
||||||
GSS_C_NO_CREDENTIAL,
|
|
||||||
&handle,
|
|
||||||
princ,
|
|
||||||
GSS_C_NO_OID,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
GSS_C_NO_CHANNEL_BINDINGS,
|
|
||||||
&in,
|
|
||||||
NULL,
|
|
||||||
&out,
|
|
||||||
0,
|
|
||||||
0);
|
|
||||||
if (GSS_ERROR(major))
|
|
||||||
{
|
|
||||||
report_error(major, minor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/** We successfully requested the token, send it to the backend server */
|
|
||||||
GWBUF* buffer = gwbuf_alloc(MYSQL_HEADER_LEN + out.length);
|
|
||||||
|
|
||||||
if (buffer)
|
if (buffer)
|
||||||
{
|
{
|
||||||
uint8_t* data = (uint8_t*)GWBUF_DATA(buffer);
|
uint8_t* data = (uint8_t*)GWBUF_DATA(buffer);
|
||||||
gw_mysql_set_byte3(data, out.length);
|
gw_mysql_set_byte3(data, ses->auth_token_len);
|
||||||
data += 3;
|
data += 3;
|
||||||
*data++ = ++auth->sequence;
|
*data++ = ++auth->sequence;
|
||||||
memcpy(data, out.value, out.length);
|
memcpy(data, ses->auth_token, ses->auth_token_len);
|
||||||
|
|
||||||
if (dcb_write(dcb, buffer))
|
if (dcb_write(dcb, buffer))
|
||||||
{
|
{
|
||||||
@ -116,21 +79,6 @@ static bool send_new_auth_token(DCB* dcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
major = gss_delete_sec_context(&minor, &handle, &in);
|
|
||||||
|
|
||||||
if (GSS_ERROR(major))
|
|
||||||
{
|
|
||||||
report_error(major, minor);
|
|
||||||
}
|
|
||||||
|
|
||||||
major = gss_release_name(&minor, &princ);
|
|
||||||
|
|
||||||
if (GSS_ERROR(major))
|
|
||||||
{
|
|
||||||
report_error(major, minor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user