MXS-2794: Log changes in loaded users
By checking whether the users have changed whenever they are reloaded, we improve the visibility of the user reloading process. Using a checksum allows us to easily compress the information with acceptable loss of accuracy. Using a CAS loop prevents duplicate messages without losing any updates even if multiple user reloads result in different outcomes.
This commit is contained in:
@ -1143,6 +1143,42 @@ bool query_and_process_users(const char* query, MYSQL* con, SERVICE* service, in
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void log_loaded_users(MYSQL_AUTH* instance, SERVICE* service, Listener* port, SERVER* srv,
|
||||||
|
const std::vector<User>& userlist, const std::vector<std::string>& dblist)
|
||||||
|
{
|
||||||
|
uint64_t c = crc32(0, 0, 0);
|
||||||
|
|
||||||
|
for (const auto& user : userlist)
|
||||||
|
{
|
||||||
|
c = crc32(c, (uint8_t*)user.user.c_str(), user.user.length());
|
||||||
|
c = crc32(c, (uint8_t*)user.host.c_str(), user.host.length());
|
||||||
|
c = crc32(c, (uint8_t*)user.db.c_str(), user.db.length());
|
||||||
|
uint8_t anydb = user.anydb;
|
||||||
|
c = crc32(c, &anydb, sizeof(anydb));
|
||||||
|
c = crc32(c, (uint8_t*)user.pw.c_str(), user.pw.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& db : dblist)
|
||||||
|
{
|
||||||
|
c = crc32(c, (uint8_t*)db.c_str(), db.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t old_c = instance->checksum;
|
||||||
|
|
||||||
|
while (old_c != c)
|
||||||
|
{
|
||||||
|
if (mxb::atomic::compare_exchange(&instance->checksum, &old_c, c,
|
||||||
|
mxb::atomic::RELAXED, mxb::atomic::RELAXED))
|
||||||
|
{
|
||||||
|
MXS_NOTICE("[%s] Loaded %lu MySQL users for listener '%s' from server '%s' with checksum 0x%0lx.",
|
||||||
|
service->name(), userlist.size(), port->name(), srv->name(), c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_c = instance->checksum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int get_users_from_server(MYSQL* con, SERVER* server, SERVICE* service, Listener* listener)
|
int get_users_from_server(MYSQL* con, SERVER* server, SERVICE* service, Listener* listener)
|
||||||
{
|
{
|
||||||
auto server_version = server->version();
|
auto server_version = server->version();
|
||||||
@ -1216,6 +1252,8 @@ int get_users_from_server(MYSQL* con, SERVER* server, SERVICE* service, Listener
|
|||||||
|
|
||||||
if (rv)
|
if (rv)
|
||||||
{
|
{
|
||||||
|
log_loaded_users(instance, service, listener, server, userlist, dblist);
|
||||||
|
|
||||||
auto func = [instance, userlist, dblist]() {
|
auto func = [instance, userlist, dblist]() {
|
||||||
sqlite3* handle = get_handle(instance);
|
sqlite3* handle = get_handle(instance);
|
||||||
|
|
||||||
|
@ -192,6 +192,7 @@ static void* mysql_auth_init(char** options)
|
|||||||
instance->skip_auth = false;
|
instance->skip_auth = false;
|
||||||
instance->check_permissions = true;
|
instance->check_permissions = true;
|
||||||
instance->lower_case_table_names = false;
|
instance->lower_case_table_names = false;
|
||||||
|
instance->checksum = 0;
|
||||||
|
|
||||||
for (int i = 0; options[i]; i++)
|
for (int i = 0; options[i]; i++)
|
||||||
{
|
{
|
||||||
@ -820,12 +821,6 @@ static int mysql_auth_load_users(Listener* port)
|
|||||||
" will probably fail as a result.",
|
" will probably fail as a result.",
|
||||||
service->name());
|
service->name());
|
||||||
}
|
}
|
||||||
else if (loaded > 0 && first_load)
|
|
||||||
{
|
|
||||||
mxb_assert(srv);
|
|
||||||
MXS_NOTICE("[%s] Loaded %d MySQL users for listener %s from server %s.",
|
|
||||||
service->name(), loaded, port->name(), srv->name());
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ typedef struct mysql_auth
|
|||||||
bool skip_auth; /**< Authentication will always be successful */
|
bool skip_auth; /**< Authentication will always be successful */
|
||||||
bool check_permissions;
|
bool check_permissions;
|
||||||
bool lower_case_table_names; /**< Disable database case-sensitivity */
|
bool lower_case_table_names; /**< Disable database case-sensitivity */
|
||||||
|
uint64_t checksum;
|
||||||
} MYSQL_AUTH;
|
} MYSQL_AUTH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user