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 | |
30 | extern struct st_maria_plugin *mysql_optional_plugins[]; |
31 | extern struct st_maria_plugin *mysql_mandatory_plugins[]; |
32 | static void encryption_plugin_init(int argc, char **argv); |
33 | |
34 | extern char *xb_plugin_load; |
35 | extern char *xb_plugin_dir; |
36 | |
37 | const int PLUGIN_MAX_ARGS = 1024; |
38 | std::vector<std::string> backup_plugins_args; |
39 | |
40 | const 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 | |
45 | std::string encryption_plugin_config; |
46 | |
47 | static 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 | |
52 | static char XTRABACKUP_EXE[] = "xtrabackup" ; |
53 | |
54 | void 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 | |
133 | const char *encryption_plugin_get_config() |
134 | { |
135 | return encryption_plugin_config.c_str(); |
136 | } |
137 | |
138 | extern int finalize_encryption_plugin(st_plugin_int *plugin); |
139 | |
140 | |
141 | void 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 | |
164 | static 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 | |