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:
Markus Makela
2016-10-18 14:06:32 +03:00
parent 693d8dcbb4
commit fe689504b0
5 changed files with 79 additions and 6 deletions

View File

@ -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
```

View File

@ -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

View File

@ -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.",

View File

@ -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
{

View File

@ -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;
}
/**