30 #include <my_global.h>
34 #include <my_pthread.h>
36 #include <sql_common.h>
46 static my_bool initialized= 0;
49 static const char *plugin_declarations_sym=
"_mysql_client_plugin_declaration_";
50 static uint plugin_version[MYSQL_CLIENT_MAX_PLUGINS]=
54 MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION
68 static int is_not_initialized(
MYSQL *mysql,
const char *
name)
73 set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
74 unknown_sqlstate, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
75 name,
"not initialized");
90 find_plugin(
const char *name,
int type)
94 DBUG_ASSERT(initialized);
95 DBUG_ASSERT(type >= 0 && type < MYSQL_CLIENT_MAX_PLUGINS);
96 if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS)
99 for (p= plugin_list[type]; p; p= p->next)
101 if (strcmp(p->plugin->name, name) == 0)
122 int argc, va_list args)
128 DBUG_ASSERT(initialized);
130 plugin_int.plugin= plugin;
131 plugin_int.dlhandle= dlhandle;
133 if (plugin->type >= MYSQL_CLIENT_MAX_PLUGINS)
135 errmsg=
"Unknown client plugin type";
139 if (plugin->interface_version < plugin_version[plugin->type] ||
140 (plugin->interface_version >> 8) >
141 (plugin_version[plugin->type] >> 8))
143 errmsg=
"Incompatible client plugin interface";
148 if (plugin->init && plugin->init(errbuf,
sizeof(errbuf), argc, args))
155 memdup_root(&mem_root, &plugin_int,
sizeof(plugin_int));
159 errmsg=
"Out of memory";
165 p->next= plugin_list[plugin->type];
166 plugin_list[plugin->type]= p;
167 net_clear_error(&mysql->net);
175 set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
176 ER(CR_AUTH_PLUGIN_CANNOT_LOAD), plugin->name,
192 retval= do_add_plugin(mysql, plugin, dlhandle, argc, ap);
201 int argc, va_list args)
203 return do_add_plugin(mysql, plugin, dlhandle, argc, args);
223 static void load_env_plugins(
MYSQL *mysql)
225 char *plugs, *free_env, *s= getenv(
"LIBMYSQL_PLUGINS");
226 char *enable_cleartext_plugin= getenv(
"LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN");
228 if (enable_cleartext_plugin && strchr(
"1Yy", enable_cleartext_plugin[0]))
229 libmysql_cleartext_plugin_enabled= 1;
235 free_env= plugs= my_strdup(s, MYF(MY_WME));
238 if ((s= strchr(plugs,
';')))
266 memset(&mysql, 0,
sizeof(mysql));
269 init_alloc_root(&mem_root, 128, 128);
271 memset(&plugin_list, 0,
sizeof(plugin_list));
277 for (builtin= mysql_client_builtins; *builtin; builtin++)
278 add_plugin_noargs(&mysql, *builtin, 0, 0);
282 load_env_plugins(&mysql);
300 for (i=0; i < MYSQL_CLIENT_MAX_PLUGINS; i++)
301 for (p= plugin_list[i]; p; p= p->next)
303 if (p->plugin->deinit)
306 dlclose(p->dlhandle);
309 memset(&plugin_list, 0,
sizeof(plugin_list));
311 free_root(&mem_root, MYF(0));
322 if (is_not_initialized(mysql, plugin->name))
328 if (find_plugin(plugin->name, plugin->type))
330 set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD,
331 unknown_sqlstate, ER(CR_AUTH_PLUGIN_CANNOT_LOAD),
332 plugin->name,
"it is already loaded");
336 plugin= add_plugin_noargs(mysql, plugin, 0, 0);
345 int argc, va_list args)
348 char dlpath[FN_REFLEN+1];
349 void *sym, *dlhandle;
351 const char *plugindir;
353 char win_errormsg[2048];
356 DBUG_ENTER (
"mysql_load_plugin_v");
357 DBUG_PRINT (
"entry", (
"name=%s type=%d int argc=%d", name, type, argc));
358 if (is_not_initialized(mysql, name))
360 DBUG_PRINT (
"leave", (
"mysql not initialized"));
367 if (type >= 0 && find_plugin(name, type))
369 errmsg=
"it is already loaded";
373 if (mysql->options.extension && mysql->options.extension->plugin_dir)
375 plugindir= mysql->options.extension->plugin_dir;
379 plugindir= getenv(
"LIBMYSQL_PLUGIN_DIR");
382 plugindir= PLUGINDIR;
387 strxnmov(dlpath,
sizeof(dlpath) - 1,
389 name, SO_EXT, NullS);
391 DBUG_PRINT (
"info", (
"dlopeninig %s", dlpath));
393 if (!(dlhandle= dlopen(dlpath, RTLD_NOW)))
395 #if defined(__APPLE__)
397 strxnmov(dlpath,
sizeof(dlpath) - 1,
398 mysql->options.extension && mysql->options.extension->plugin_dir ?
399 mysql->options.extension->plugin_dir : PLUGINDIR,
"/",
401 if ((dlhandle= dlopen(dlpath, RTLD_NOW)))
407 if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
408 0, GetLastError(), 0, win_errormsg, 2048, NULL))
409 errmsg= win_errormsg;
415 DBUG_PRINT (
"info", (
"failed to dlopen"));
419 #if defined(__APPLE__)
422 if (!(sym= dlsym(dlhandle, plugin_declarations_sym)))
424 errmsg=
"not a plugin";
431 if (type >=0 && type != plugin->type)
433 errmsg=
"type mismatch";
437 if (strcmp(name, plugin->name))
439 errmsg=
"name mismatch";
443 if (type < 0 && find_plugin(name, plugin->type))
445 errmsg=
"it is already loaded";
449 plugin= add_plugin_withargs(mysql, plugin, dlhandle, argc, args);
453 DBUG_PRINT (
"leave", (
"plugin loaded ok"));
454 DBUG_RETURN (plugin);
458 DBUG_PRINT (
"leave", (
"plugin load error : %s", errmsg));
459 set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
460 ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name, errmsg);
470 va_start(args, argc);
482 DBUG_ENTER (
"mysql_client_find_plugin");
483 DBUG_PRINT (
"entry", (
"name=%s, type=%d", name, type));
484 if (is_not_initialized(mysql, name))
487 if (type < 0 || type >= MYSQL_CLIENT_MAX_PLUGINS)
489 set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_CANNOT_LOAD, unknown_sqlstate,
490 ER(CR_AUTH_PLUGIN_CANNOT_LOAD), name,
494 if ((p= find_plugin(name, type)))
496 DBUG_PRINT (
"leave", (
"found %p", p));
502 DBUG_PRINT (
"leave", (
"loaded %p", p));
512 DBUG_ENTER(
"mysql_plugin_options");
514 if (!plugin || !plugin->options)
516 DBUG_RETURN(plugin->options(option, value));