1/* Copyright (c) 2017, MariaDB Corporation.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15
16#include <my_global.h>
17#include <mysqld.h>
18#include <mysql.h>
19#include <xtrabackup.h>
20#include <encryption_plugin.h>
21#include <backup_copy.h>
22#include <sql_plugin.h>
23#include <sstream>
24#include <vector>
25#include <common.h>
26#include <backup_mysql.h>
27#include <log0crypt.h>
28
29
30extern struct st_maria_plugin *mysql_optional_plugins[];
31extern struct st_maria_plugin *mysql_mandatory_plugins[];
32static void encryption_plugin_init(int argc, char **argv);
33
34extern char *xb_plugin_load;
35extern char *xb_plugin_dir;
36
37const int PLUGIN_MAX_ARGS = 1024;
38std::vector<std::string> backup_plugins_args;
39
40const char *QUERY_PLUGIN =
41"SELECT plugin_name, plugin_library, @@plugin_dir"
42" FROM information_schema.plugins WHERE plugin_type='ENCRYPTION'"
43" AND plugin_status='ACTIVE'";
44
45std::string encryption_plugin_config;
46
47static void add_to_plugin_load_list(const char *plugin_def)
48{
49 opt_plugin_load_list_ptr->push_back(new i_string(plugin_def));
50}
51
52static char XTRABACKUP_EXE[] = "xtrabackup";
53
54void encryption_plugin_backup_init(MYSQL *mysql)
55{
56 MYSQL_RES *result;
57 MYSQL_ROW row;
58 std::ostringstream oss;
59 char *argv[PLUGIN_MAX_ARGS];
60 int argc;
61
62 result = xb_mysql_query(mysql, QUERY_PLUGIN, true, true);
63 row = mysql_fetch_row(result);
64 if (!row)
65 {
66 mysql_free_result(result);
67 return;
68 }
69
70 char *name= row[0];
71 char *library= row[1];
72 char *dir= row[2];
73
74#ifdef _WIN32
75 for (char *p = dir; *p; p++)
76 if (*p == '\\') *p = '/';
77#endif
78
79 std::string plugin_load(name);
80 if (library)
81 plugin_load += std::string("=") + library;
82
83 oss << "plugin_load=" << plugin_load << std::endl;
84
85 /* Required to load the plugin later.*/
86 add_to_plugin_load_list(plugin_load.c_str());
87 strncpy(opt_plugin_dir, dir, FN_REFLEN);
88
89 oss << "plugin_dir=" << '"' << dir << '"' << std::endl;
90
91
92 /* Read plugin variables. */
93 char query[1024];
94 snprintf(query, 1024, "SHOW variables like '%s_%%'", name);
95 mysql_free_result(result);
96
97 result = xb_mysql_query(mysql, query, true, true);
98 while ((row = mysql_fetch_row(result)))
99 {
100 std::string arg("--");
101 arg += row[0];
102 arg += "=";
103 arg += row[1];
104 backup_plugins_args.push_back(arg);
105 oss << row[0] << "=" << row[1] << std::endl;
106 }
107
108 mysql_free_result(result);
109
110 /* Check whether to encrypt logs. */
111 result = xb_mysql_query(mysql, "select @@innodb_encrypt_log", true, true);
112 row = mysql_fetch_row(result);
113 srv_encrypt_log = (row != 0 && row[0][0] == '1');
114 oss << "innodb_encrypt_log=" << row[0] << std::endl;
115
116 mysql_free_result(result);
117
118 encryption_plugin_config = oss.str();
119
120 argc = 0;
121 argv[argc++] = XTRABACKUP_EXE;
122 for(size_t i = 0; i < backup_plugins_args.size(); i++)
123 {
124 argv[argc++] = (char *)backup_plugins_args[i].c_str();
125 if (argc == PLUGIN_MAX_ARGS - 2)
126 break;
127 }
128 argv[argc] = 0;
129
130 encryption_plugin_init(argc, argv);
131}
132
133const char *encryption_plugin_get_config()
134{
135 return encryption_plugin_config.c_str();
136}
137
138extern int finalize_encryption_plugin(st_plugin_int *plugin);
139
140
141void encryption_plugin_prepare_init(int argc, char **argv)
142{
143
144 if (!xb_plugin_load)
145 {
146 finalize_encryption_plugin(0);
147 return;
148 }
149
150 add_to_plugin_load_list(xb_plugin_load);
151
152 if (xb_plugin_dir)
153 strncpy(opt_plugin_dir, xb_plugin_dir, FN_REFLEN);
154
155 char **new_argv = new char *[argc + 1];
156 new_argv[0] = XTRABACKUP_EXE;
157 memcpy(&new_argv[1], argv, argc*sizeof(char *));
158
159 encryption_plugin_init(argc+1, new_argv);
160
161 delete[] new_argv;
162}
163
164static void encryption_plugin_init(int argc, char **argv)
165{
166 /* Patch optional and mandatory plugins, we only need to load the one in xb_plugin_load. */
167 mysql_optional_plugins[0] = mysql_mandatory_plugins[0] = 0;
168 plugin_maturity = MariaDB_PLUGIN_MATURITY_UNKNOWN; /* mariabackup accepts all plugins */
169 msg("Loading encryption plugin\n");
170 for (int i= 1; i < argc; i++)
171 msg("\t Encryption plugin parameter : '%s'\n", argv[i]);
172 plugin_init(&argc, argv, PLUGIN_INIT_SKIP_PLUGIN_TABLE);
173}
174
175