千家信息网

PostgreSQL插件hook机制

发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,internal_load_library postgresql-> PG_init = (PG_init_t) pg_dlsym(file_scanner->handle, "_PG_init
千家信息网最后更新 2025年01月24日PostgreSQL插件hook机制
internal_load_library postgresql->    PG_init = (PG_init_t) pg_dlsym(file_scanner->handle, "_PG_init");    if (PG_init)            (*PG_init) ();internal_unload_library(const char *libname)->    PG_fini = (PG_fini_t) pg_dlsym(file_scanner->handle, "_PG_fini");            if (PG_fini)                (*PG_fini) ();以ClientAuthentication_hook_type为例auth.h://声明插件使用的函数extern void ClientAuthentication(Port *port);/* Hook for plugins to get control in ClientAuthentication() */typedef void (*ClientAuthentication_hook_type) (Port *, int);extern PGDLLIMPORT ClientAuthentication_hook_type ClientAuthentication_hook;auth.c://全局变量初始化为NULL,在_PG_init函数中进行初始化赋值,如果该插件加载,则ClientAuthentication_hook为ClientAuthentication_hook_type ClientAuthentication_hook = NULL;//如果ClientAuthentication_hook被赋值则执行植入的代码InitPostgres->PerformAuthentication->ClientAuthentication->    if (ClientAuthentication_hook)        (*ClientAuthentication_hook) (port, status);auth_delay.c:static ClientAuthentication_hook_type original_client_auth_hook = NULL;/* * Module Load Callback */void _PG_init(void){    /* Define custom GUC variables */    DefineCustomIntVariable("auth_delay.milliseconds",                            "Milliseconds to delay before reporting authentication failure",                            NULL,                            &auth_delay_milliseconds,                            0,                            0, INT_MAX / 1000,                            PGC_SIGHUP,                            GUC_UNIT_MS,                            NULL,                            NULL,                            NULL);    /* Install Hooks */    original_client_auth_hook = ClientAuthentication_hook;    ClientAuthentication_hook = auth_delay_checks;}/*如果卸载则调用该函数,实际上是将ClientAuthentication_hook赋回原值*/void_PG_fini(void){    ClientAuthentication_hook=original_client_auth_hook;}/**/static void auth_delay_checks(Port *port, int status){    if (original_client_auth_hook)        original_client_auth_hook(port, status);    if (status != STATUS_OK){        pg_usleep(1000L * auth_delay_milliseconds);    }}
0