MySQL 8.0.40
Source Code Documentation
version_token.cc File Reference
#include <assert.h>
#include <mysql/components/my_service.h>
#include <mysql/components/services/dynamic_privilege.h>
#include <mysql/plugin_audit.h>
#include <mysql/psi/mysql_memory.h>
#include <mysql/psi/mysql_rwlock.h>
#include <mysql/service_locking.h>
#include <sys/types.h>
#include <algorithm>
#include <atomic>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "errmsg.h"
#include "lex_string.h"
#include "m_string.h"
#include "map_helpers.h"
#include "my_compiler.h"
#include "my_inttypes.h"
#include "my_psi_config.h"
#include "my_systime.h"
#include "sql/auth/auth_acls.h"
#include "sql/current_thd.h"
#include "sql/derror.h"
#include "sql/locking_service.h"
#include "sql/sql_class.h"
#include "sql/sql_lex.h"

Classes

class  atomic_boolean
 Utility class implementing an atomic boolean on top of an int32. More...
 
class  vtoken_lock_cleanup
 Helper class to dispose of the rwlocks at DLL/so unload. More...
 

Macros

#define PLUGIN_EXPORT   extern "C"
 
#define VTOKEN_LOCKS_NAMESPACE   "version_token_locks"
 
#define LONG_TIMEOUT   ((ulong)3600L * 24L * 365L)
 

Enumerations

enum  command { SET_VTOKEN = 0 , EDIT_VTOKEN , CHECK_VTOKEN }
 

Functions

static MYSQL_THDVAR_ULONG (session_number, PLUGIN_VAR_RQCMDARG|PLUGIN_VAR_READONLY|PLUGIN_VAR_NOPERSIST, "Version number to assist with session tokens check", nullptr, nullptr, 0L, 0,((ulong) -1), 0)
 
static void update_session_version_tokens (MYSQL_THD thd, SYS_VAR *, void *var_ptr, const void *save)
 
static MYSQL_THDVAR_STR (session, PLUGIN_VAR_RQCMDARG|PLUGIN_VAR_MEMALLOC, "Holds the session value for version tokens", nullptr, update_session_version_tokens, nullptr)
 
static void vtoken_init_psi_keys (void)
 
static bool is_blank_string (char *input)
 
bool has_required_privileges (THD *thd)
 Check if user either has SUPER or VERSION_TOKEN_ADMIN privileges. More...
 
static void set_vtoken_string_length ()
 
PLUGIN_EXPORT bool version_tokens_set_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
 
PLUGIN_EXPORT char * version_tokens_set (UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, unsigned char *null_value, unsigned char *error)
 
PLUGIN_EXPORT bool version_tokens_show_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
 
PLUGIN_EXPORT void version_tokens_show_deinit (UDF_INIT *initid)
 
PLUGIN_EXPORT char * version_tokens_show (UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, unsigned char *null_value, unsigned char *error)
 
PLUGIN_EXPORT bool version_tokens_edit_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
 
PLUGIN_EXPORT char * version_tokens_edit (UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, unsigned char *null_value, unsigned char *error)
 
PLUGIN_EXPORT bool version_tokens_delete_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
 
PLUGIN_EXPORT char * version_tokens_delete (UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, unsigned char *null_value, unsigned char *error)
 
PLUGIN_EXPORT bool version_tokens_lock_shared_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
 
PLUGIN_EXPORT long long version_tokens_lock_shared (UDF_INIT *initid, UDF_ARGS *args, unsigned char *is_null, unsigned char *error)
 
PLUGIN_EXPORT bool version_tokens_lock_exclusive_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
 
PLUGIN_EXPORT long long version_tokens_lock_exclusive (UDF_INIT *initid, UDF_ARGS *args, unsigned char *is_null, unsigned char *error)
 
PLUGIN_EXPORT bool version_tokens_unlock_init (UDF_INIT *initid, UDF_ARGS *args, char *message)
 
PLUGIN_EXPORT long long version_tokens_unlock (UDF_INIT *initid, UDF_ARGS *args, unsigned char *is_null, unsigned char *error)
 
static int parse_vtokens (char *input, enum command type)
 Parses the list of version tokens and either updates the global list with the input or checks the input against the global according to which function the caller is. More...
 
static int version_token_check (MYSQL_THD thd, mysql_event_class_t event_class, const void *event)
 Audit API entry point for the version token plugin. More...
 
static int version_tokens_init (void *arg)
 Plugin init. More...
 
static int version_tokens_deinit (void *arg)
 Plugin deinit. More...
 
 mysql_declare_plugin (version_tokens)
 
static bool is_hash_inited (const char *function, unsigned char *error)
 A function to check if the hash is inited and generate an error. More...
 
static bool init_acquire (UDF_INIT *initid, UDF_ARGS *args, char *message)
 

Variables

static std::atomic< int64session_number {1}
 
static size_t vtoken_string_length
 
PSI_memory_key key_memory_vtoken
 
static malloc_unordered_map< string, string > * version_tokens_hash
 
static atomic_boolean version_tokens_hash_inited
 State of the version tokens hash global structure. More...
 
mysql_rwlock_t LOCK_vtoken_hash
 
PSI_rwlock_key key_LOCK_vtoken_hash
 
static PSI_rwlock_info all_vtoken_rwlocks []
 
static PSI_memory_info all_vtoken_memory []
 
static vtoken_lock_cleanup cleanup_lock
 A single global variable to invoke the destructor. More...
 
static struct st_mysql_audit version_token_descriptor
 
static SYS_VARsystem_variables []
 
 mysql_declare_plugin_end
 

Macro Definition Documentation

◆ LONG_TIMEOUT

#define LONG_TIMEOUT   ((ulong)3600L * 24L * 365L)

◆ PLUGIN_EXPORT

#define PLUGIN_EXPORT   extern "C"

◆ VTOKEN_LOCKS_NAMESPACE

#define VTOKEN_LOCKS_NAMESPACE   "version_token_locks"

Enumeration Type Documentation

◆ command

enum command
Enumerator
SET_VTOKEN 
EDIT_VTOKEN 
CHECK_VTOKEN 

Function Documentation

◆ has_required_privileges()

bool has_required_privileges ( THD thd)

Check if user either has SUPER or VERSION_TOKEN_ADMIN privileges.

Parameters
thdThread handle
Returns
success state
Return values
trueUser has the required privileges
falseUser has not the required privileges

◆ init_acquire()

static bool init_acquire ( UDF_INIT initid,
UDF_ARGS args,
char *  message 
)
inlinestatic

◆ is_blank_string()

static bool is_blank_string ( char *  input)
static

◆ is_hash_inited()

static bool is_hash_inited ( const char *  function,
unsigned char *  error 
)
static

A function to check if the hash is inited and generate an error.

To be called while holding LOCK_vtoken_hash

Parameters
functionthe UDF function name for the error message
errorthe UDF error pointer to set
Return values
falsehash not initialized. Error set. Bail out.
trueAll good. Go on.

◆ mysql_declare_plugin()

mysql_declare_plugin ( version_tokens  )

◆ MYSQL_THDVAR_STR()

static MYSQL_THDVAR_STR ( session  ,
PLUGIN_VAR_RQCMDARG PLUGIN_VAR_MEMALLOC,
"Holds the session value for version tokens"  ,
nullptr  ,
update_session_version_tokens  ,
nullptr   
)
static

◆ MYSQL_THDVAR_ULONG()

static MYSQL_THDVAR_ULONG ( session_number  ,
PLUGIN_VAR_RQCMDARG|PLUGIN_VAR_READONLY PLUGIN_VAR_NOPERSIST,
"Version number to assist with session tokens check"  ,
nullptr  ,
nullptr  ,
0L  ,
,
((ulong) -1)  ,
 
)
static

◆ parse_vtokens()

static int parse_vtokens ( char *  input,
enum command  type 
)
static

Parses the list of version tokens and either updates the global list with the input or checks the input against the global according to which function the caller is.

Parameters
[in]inputList of semicolon separated token name/value pairs
[in]typeHelps determining the caller function.
Returns
(error) -1 in case of error.
(success) Number of tokens updated/set on EDIT_VTOKEN and SET_VTOKEN. 0 in case of CHECK_VTOKEN.

TODO: Add calls to get_lock services in CHECK_VTOKEN.

◆ set_vtoken_string_length()

static void set_vtoken_string_length ( )
static

◆ update_session_version_tokens()

static void update_session_version_tokens ( MYSQL_THD  thd,
SYS_VAR ,
void *  var_ptr,
const void *  save 
)
static

◆ version_token_check()

static int version_token_check ( MYSQL_THD  thd,
mysql_event_class_t  event_class,
const void *  event 
)
static

Audit API entry point for the version token plugin.

Plugin audit function to compare session version tokens with the global ones. At the start of each query (MYSQL_AUDIT_GENERAL_LOG currently) if there's a session version token vector it will acquire the GET_LOCK shared locks for the session version tokens and then will try to find them in the global version lock and compare their values with the ones found. Throws errors if not found or the version values do not match. See parse_vtokens(). At query end (MYSQL_AUDIT_GENERAL_STATUS currently) it releases the GET_LOCK shared locks it has acquired.

Parameters
thdThe current thread
event_classaudit API event class
eventpointer to the audit API event data

◆ version_tokens_deinit()

static int version_tokens_deinit ( void *  arg)
static

Plugin deinit.

◆ version_tokens_delete()

PLUGIN_EXPORT char * version_tokens_delete ( UDF_INIT initid,
UDF_ARGS args,
char *  result,
unsigned long *  length,
unsigned char *  null_value,
unsigned char *  error 
)

◆ version_tokens_delete_init()

PLUGIN_EXPORT bool version_tokens_delete_init ( UDF_INIT initid,
UDF_ARGS args,
char *  message 
)

◆ version_tokens_edit()

PLUGIN_EXPORT char * version_tokens_edit ( UDF_INIT initid,
UDF_ARGS args,
char *  result,
unsigned long *  length,
unsigned char *  null_value,
unsigned char *  error 
)

◆ version_tokens_edit_init()

PLUGIN_EXPORT bool version_tokens_edit_init ( UDF_INIT initid,
UDF_ARGS args,
char *  message 
)

◆ version_tokens_init()

static int version_tokens_init ( void *  arg)
static

Plugin init.

◆ version_tokens_lock_exclusive()

PLUGIN_EXPORT long long version_tokens_lock_exclusive ( UDF_INIT initid,
UDF_ARGS args,
unsigned char *  is_null,
unsigned char *  error 
)

◆ version_tokens_lock_exclusive_init()

PLUGIN_EXPORT bool version_tokens_lock_exclusive_init ( UDF_INIT initid,
UDF_ARGS args,
char *  message 
)

◆ version_tokens_lock_shared()

PLUGIN_EXPORT long long version_tokens_lock_shared ( UDF_INIT initid,
UDF_ARGS args,
unsigned char *  is_null,
unsigned char *  error 
)

◆ version_tokens_lock_shared_init()

PLUGIN_EXPORT bool version_tokens_lock_shared_init ( UDF_INIT initid,
UDF_ARGS args,
char *  message 
)

◆ version_tokens_set()

PLUGIN_EXPORT char * version_tokens_set ( UDF_INIT initid,
UDF_ARGS args,
char *  result,
unsigned long *  length,
unsigned char *  null_value,
unsigned char *  error 
)

◆ version_tokens_set_init()

PLUGIN_EXPORT bool version_tokens_set_init ( UDF_INIT initid,
UDF_ARGS args,
char *  message 
)

◆ version_tokens_show()

PLUGIN_EXPORT char * version_tokens_show ( UDF_INIT initid,
UDF_ARGS args,
char *  result,
unsigned long *  length,
unsigned char *  null_value,
unsigned char *  error 
)

◆ version_tokens_show_deinit()

PLUGIN_EXPORT void version_tokens_show_deinit ( UDF_INIT initid)

◆ version_tokens_show_init()

PLUGIN_EXPORT bool version_tokens_show_init ( UDF_INIT initid,
UDF_ARGS args,
char *  message 
)

◆ version_tokens_unlock()

long long version_tokens_unlock ( UDF_INIT initid,
UDF_ARGS args,
unsigned char *  is_null,
unsigned char *  error 
)

◆ version_tokens_unlock_init()

PLUGIN_EXPORT bool version_tokens_unlock_init ( UDF_INIT initid,
UDF_ARGS args,
char *  message 
)

◆ vtoken_init_psi_keys()

static void vtoken_init_psi_keys ( void  )
static

Variable Documentation

◆ all_vtoken_memory

PSI_memory_info all_vtoken_memory[]
static
Initial value:
= {
{&key_memory_vtoken, "vtoken", 0, 0, PSI_DOCUMENT_ME}}
#define PSI_DOCUMENT_ME
Definition: component_common.h:29
PSI_memory_key key_memory_vtoken
Definition: version_token.cc:76

◆ all_vtoken_rwlocks

PSI_rwlock_info all_vtoken_rwlocks[]
static
Initial value:
= {
{&key_LOCK_vtoken_hash, "LOCK_vtoken_hash", 0, 0, PSI_DOCUMENT_ME},
}
PSI_rwlock_key key_LOCK_vtoken_hash
Definition: version_token.cc:158

◆ cleanup_lock

vtoken_lock_cleanup cleanup_lock
static

A single global variable to invoke the destructor.

See vtoken_lock_cleanup.

◆ key_LOCK_vtoken_hash

PSI_rwlock_key key_LOCK_vtoken_hash

◆ key_memory_vtoken

PSI_memory_key key_memory_vtoken

◆ LOCK_vtoken_hash

mysql_rwlock_t LOCK_vtoken_hash

◆ mysql_declare_plugin_end

mysql_declare_plugin_end

◆ session_number

std::atomic<int64> session_number {1}
static

◆ system_variables

SYS_VAR* system_variables[]
static
Initial value:
MYSQL_SYSVAR(session), nullptr}
#define MYSQL_SYSVAR(name)
Definition: plugin.h:252
static std::atomic< int64 > session_number
Definition: version_token.cc:69

◆ version_token_descriptor

struct st_mysql_audit version_token_descriptor
static
Initial value:
= {
nullptr,
{
(unsigned long)MYSQL_AUDIT_GENERAL_ALL,
}
}
#define MYSQL_AUDIT_INTERFACE_VERSION
Definition: plugin_audit.h:41
#define MYSQL_AUDIT_GENERAL_ALL
Definition: plugin_audit.h:123
static int version_token_check(MYSQL_THD thd, mysql_event_class_t event_class, const void *event)
Audit API entry point for the version token plugin.
Definition: version_token.cc:441

◆ version_tokens_hash

malloc_unordered_map<string, string>* version_tokens_hash
static

◆ version_tokens_hash_inited

atomic_boolean version_tokens_hash_inited
static

State of the version tokens hash global structure.

Needed since both the UDFs and the plugin are using the global and thus it can't be freed until the last UDF or plugin has been unloaded.

◆ vtoken_string_length

size_t vtoken_string_length
static