Move service user injection into MySQL authenticator
The MySQL authenticator now injects the service user into the list of allowed users if loading of database users fails. This allows the removal of common code in the binlogrouter and maxinfo modules.
This commit is contained in:
@ -32,3 +32,21 @@ port=4006
|
||||
authenticator=MySQLAuth
|
||||
authenticator_options=cache_dir=/tmp
|
||||
```
|
||||
|
||||
### `inject_service_user`
|
||||
|
||||
Inject service credentials into the list of database users if loading of
|
||||
users fails. This option takes a boolean value and it is enabled by
|
||||
default.
|
||||
|
||||
When a connection to the backend database cannot be made, the service user
|
||||
can be injected into the list of allowed users. This allows administrative
|
||||
operations to be done via the SQL interface with modules that support it
|
||||
e.g. the Binlogrouter and Maxinfo modules.
|
||||
|
||||
If users are loaded successfully, the service user credentials are _not_
|
||||
injected into the list of users.
|
||||
|
||||
```
|
||||
authenticator_options=inject_service_user=false
|
||||
```
|
||||
|
@ -100,9 +100,7 @@ typedef enum router_capability_t
|
||||
RCAP_TYPE_UNDEFINED = 0x00,
|
||||
RCAP_TYPE_STMT_INPUT = 0x01, /**< Statement per buffer */
|
||||
RCAP_TYPE_PACKET_INPUT = 0x02, /**< Data as it was read from DCB */
|
||||
RCAP_TYPE_NO_RSESSION = 0x04, /**< Router does not use router sessions */
|
||||
RCAP_TYPE_NO_USERS_INIT = 0x08 /**< Prevent the loading of authenticator
|
||||
users when the service is started */
|
||||
RCAP_TYPE_NO_RSESSION = 0x04 /**< Router does not use router sessions */
|
||||
} router_capability_t;
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -303,7 +303,6 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port)
|
||||
|
||||
/** Load the authentication users before before starting the listener */
|
||||
if (port->listener->authfunc.loadusers &&
|
||||
(service->router->getCapabilities() & RCAP_TYPE_NO_USERS_INIT) == 0 &&
|
||||
port->listener->authfunc.loadusers(port) != MXS_AUTH_LOADUSERS_OK)
|
||||
{
|
||||
MXS_ERROR("[%s] Failed to load users for listener '%s', authentication might not work.",
|
||||
|
@ -37,7 +37,8 @@
|
||||
|
||||
typedef struct mysql_auth
|
||||
{
|
||||
char *cache_dir; /**< Custom cache directory location */
|
||||
char *cache_dir; /**< Custom cache directory location */
|
||||
bool inject_service_user; /**< Inject the service user into the list of users */
|
||||
} MYSQL_AUTH;
|
||||
|
||||
|
||||
@ -142,6 +143,7 @@ static void* mysql_auth_init(char **options)
|
||||
{
|
||||
bool error = false;
|
||||
instance->cache_dir = NULL;
|
||||
instance->inject_service_user = true;
|
||||
|
||||
for (int i = 0; options[i]; i++)
|
||||
{
|
||||
@ -158,6 +160,10 @@ static void* mysql_auth_init(char **options)
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
else if (strcmp(options[i], "inject_service_user") == 0)
|
||||
{
|
||||
instance->inject_service_user = config_truth_value(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Unknown authenticator option: %s", options[i]);
|
||||
@ -830,6 +836,48 @@ mysql_auth_free_client_data(DCB *dcb)
|
||||
MXS_FREE(dcb->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inject the service user into the cache
|
||||
*
|
||||
* @param port Service listener
|
||||
* @return True on success, false on error
|
||||
*/
|
||||
static bool add_service_user(SERV_LISTENER *port)
|
||||
{
|
||||
char *user = NULL;
|
||||
char *pw = NULL;
|
||||
bool rval = false;
|
||||
|
||||
if (serviceGetUser(port->service, &user, &pw))
|
||||
{
|
||||
pw = decryptPassword(pw);
|
||||
|
||||
if (pw)
|
||||
{
|
||||
char *newpw = create_hex_sha1_sha1_passwd(pw);
|
||||
|
||||
if (newpw)
|
||||
{
|
||||
add_mysql_users_with_host_ipv4(port->users, user, "%", newpw, "Y", "");
|
||||
add_mysql_users_with_host_ipv4(port->users, user, "localhost", newpw, "Y", "");
|
||||
MXS_FREE(newpw);
|
||||
rval = true;
|
||||
}
|
||||
MXS_FREE(pw);
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("[%s] Failed to decrypt service user password.", port->service->name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("[%s] Failed to retrieve service credentials.", port->service->name);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load MySQL authentication users
|
||||
*
|
||||
@ -871,6 +919,16 @@ static int mysql_auth_load_users(SERV_LISTENER *port)
|
||||
{
|
||||
MXS_WARNING("Using cached credential information.");
|
||||
}
|
||||
|
||||
if (instance->inject_service_user)
|
||||
{
|
||||
/** Inject the service user as a 'backup' user that's available
|
||||
* if loading of the users fails */
|
||||
if (!add_service_user(port))
|
||||
{
|
||||
MXS_ERROR("[%s] Failed to inject service user.", port->service->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1790,7 +1790,7 @@ static void rses_end_locked_router_action(ROUTER_SLAVE *rses)
|
||||
|
||||
static uint64_t getCapabilities()
|
||||
{
|
||||
return (RCAP_TYPE_NO_RSESSION | RCAP_TYPE_NO_USERS_INIT);
|
||||
return RCAP_TYPE_NO_RSESSION;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user