OpenDNSSEC-enforcer 2.1.12
ods-enforcer-db-setup.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 Jerry Lundström <lundstrom.jerry@gmail.com>
3 * Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
4 * Copyright (c) 2014 OpenDNSSEC AB (svb)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
34#include "config.h"
35
36#include <stdlib.h>
37#include <unistd.h>
38#include <getopt.h>
39
40#include "daemon/engine.h"
41#include "log.h"
42
43#if defined(ENFORCER_DATABASE_SQLITE3)
44#include <sqlite3.h>
45#include "db/db_schema_sqlite.h"
46#include "db/db_data_sqlite.h"
47static const char** create = db_schema_sqlite_create;
48static const char** drop = db_schema_sqlite_drop;
49static const char** data = db_data_sqlite;
50static sqlite3* db = NULL;
51#elif defined(ENFORCER_DATABASE_MYSQL)
52#include <mysql/mysql.h>
53#include "db/db_schema_mysql.h"
54#include "db/db_data_mysql.h"
55static const char** create = db_schema_mysql_create;
56static const char** drop = db_schema_mysql_drop;
57static const char** data = db_data_mysql;
58static MYSQL* db = NULL;
59#endif
60
61#define AUTHOR_NAME "Jerry Lundström"
62#define COPYRIGHT_STR "Copyright (c) 2014 .SE (The Internet Infrastructure Foundation) OpenDNSSEC"
63
64static void usage(FILE* out) {
65 fprintf(out,
66 "\nBSD licensed, see LICENSE in source package for details.\n"
67 "Version %s. Report bugs to <%s>.\n",
68 PACKAGE_VERSION,
69 PACKAGE_BUGREPORT);
70 fprintf(out, "--help, -h: Print usage.\n");
71 fprintf(out, "--version, -V: Print version.\n");
72 fprintf(out, "--force, -f: Yes to all questions.\n");
73}
74
75static void version(FILE* out) {
76 fprintf(out,
77 "Database setup tool for %s version %s\n"
78 "Written by %s.\n\n"
79 "%s. This is free software.\n"
80 "See source files for more license information\n",
81 PACKAGE_NAME,
82 PACKAGE_VERSION,
85 exit(0);
86}
87
88static int connect_db(engineconfig_type* cfg) {
89#if defined(ENFORCER_DATABASE_SQLITE3)
90 if (!cfg->datastore) {
91 return -1;
92 }
93 if (db) {
94 return -1;
95 }
96
97 if (sqlite3_initialize() != SQLITE_OK) {
98 return -1;
99 }
100
101 if (sqlite3_open_v2(cfg->datastore, &db,
102 SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_CREATE,
103 NULL) != SQLITE_OK)
104 {
105 return -1;
106 }
107
108 return 0;
109#elif defined(ENFORCER_DATABASE_MYSQL)
110 if (!cfg->datastore) {
111 return -1;
112 }
113 if (db) {
114 return -1;
115 }
116
117 if (mysql_library_init(0, NULL, NULL)) {
118 return -1;
119 }
120
121 if (!(db = mysql_init(NULL))
122 || !mysql_real_connect(db,
123 cfg->db_host,
124 cfg->db_username,
125 cfg->db_password,
126 cfg->datastore,
127 cfg->db_port,
128 NULL,
129 0))
130 {
131 if (db) {
132 mysql_close(db);
133 db = NULL;
134 }
135 return -1;
136 }
137
138 return 0;
139#else
140 return -1;
141#endif
142}
143
144static int disconnect_db() {
145#if defined(ENFORCER_DATABASE_SQLITE3)
146 if (db) {
147 sqlite3_close(db);
148 db = NULL;
149 }
150
151 sqlite3_shutdown();
152
153 return 0;
154#elif defined(ENFORCER_DATABASE_MYSQL)
155 if (db) {
156 mysql_close(db);
157 db = NULL;
158 }
159
160 mysql_library_end();
161
162 return 0;
163#else
164 return -1;
165#endif
166}
167
168static int db_do(const char *sql, size_t size) {
169#if defined(ENFORCER_DATABASE_SQLITE3)
170 sqlite3_stmt* stmt = NULL;
171
172 if (!db) {
173 return -1;
174 }
175 if (!sql) {
176 return -1;
177 }
178
179 if (sqlite3_prepare_v2(db, sql, size, &stmt, NULL) != SQLITE_OK
180 || sqlite3_step(stmt) != SQLITE_DONE)
181 {
182 if (stmt) {
183 sqlite3_finalize(stmt);
184 }
185 return -1;
186 }
187 sqlite3_finalize(stmt);
188
189 return 0;
190#elif defined(ENFORCER_DATABASE_MYSQL)
191 if (!db) {
192 return -1;
193 }
194 if (!sql) {
195 return -1;
196 }
197
198 if (mysql_real_query(db, sql, size)) {
199 return -1;
200 }
201
202 return 0;
203#else
204 return -1;
205#endif
206}
207
208static int db_do2(const char** strs) {
209 char sql[4096];
210 char *sqlp;
211 int ret, left, i;
212
213 for (i = 0; strs[i]; i++) {
214 left = sizeof(sql);
215 sqlp = sql;
216
217 for (; strs[i]; i++) {
218 if ((ret = snprintf(sqlp, left, "%s", strs[i])) >= left) {
219 return -1;
220 }
221 sqlp += ret;
222 left -= ret;
223 }
224
225 if (db_do(sql, sizeof(sql) - left)) {
226 return -1;
227 }
228 }
229
230 return 0;
231}
232
233int main(int argc, char* argv[]) {
234 int c, options_index = 0;
235 static struct option long_options[] = {
236 {"help", no_argument, 0, 'h'},
237 {"version", no_argument, 0, 'V'},
238 {"force", no_argument, 0, 'f'},
239 { 0, 0, 0, 0}
240 };
241 int user_certain;
242 int force = 0;
244 const char* cfgfile = ODS_SE_CFGFILE;
245
246 ods_log_init("ods-enforcerd", 0, NULL, 0);
247
248 while ((c=getopt_long(argc, argv, "hVf",
249 long_options, &options_index)) != -1) {
250 switch (c) {
251 case 'h':
252 usage(stdout);
253 exit(0);
254 case 'V':
255 version(stdout);
256 exit(0);
257 case 'f':
258 force = 1;
259 break;
260 default:
261 exit(100);
262 }
263 }
264
265 if (!force) {
266 printf("*WARNING* This will erase all data in the database; "
267 "are you sure? [y/N] ");
268 user_certain = getchar();
269 if (user_certain != 'y' && user_certain != 'Y') {
270 printf("Okay, quitting...\n");
271 return 0;
272 }
273 }
274
275 cfg = engine_config(cfgfile, 0, NULL);
276 if (engine_config_check(cfg) != ODS_STATUS_OK) {
278 fprintf(stderr, "Error: unable to load configuration!\n");
279 return 1;
280 }
281
282 if (connect_db(cfg)) {
284 fprintf(stderr, "Error: unable to connect to database!\n");
285 return 2;
286 }
287
288 /*
289 * Drop existing schema.
290 */
291 if (db_do2(drop)) {
292 fprintf(stderr, "Error: unable to drop existing schema!\n");
293 disconnect_db();
294 return 3;
295 }
296
297 /*
298 * Create new schema.
299 */
300 if (db_do2(create)) {
301 fprintf(stderr, "Error: unable to create schema!\n");
302 disconnect_db();
303 return 4;
304 }
305
306 /*
307 * Insert initial data.
308 */
309 if (db_do2(data)) {
310 fprintf(stderr, "Error: unable to insert initial data!\n");
311 disconnect_db();
312 return 5;
313 }
314
316 printf("Database setup successfully.\n");
317 return 0;
318}
engineconfig_type * engine_config(const char *cfgfile, int cmdline_verbosity, engineconfig_type *oldcfg)
Definition: cfg.c:59
void engine_config_cleanup(engineconfig_type *config)
Definition: cfg.c:278
ods_status engine_config_check(engineconfig_type *config)
Definition: cfg.c:155
const char * db_data_mysql[]
Definition: db_data_mysql.c:29
const char * db_data_sqlite[]
const char * db_schema_mysql_create[]
const char * db_schema_mysql_drop[]
const char * db_schema_sqlite_drop[]
const char * db_schema_sqlite_create[]
int main(int argc, char *argv[])
#define COPYRIGHT_STR
#define AUTHOR_NAME
const char * datastore
Definition: cfg.h:68
const char * db_password
Definition: cfg.h:71
const char * db_username
Definition: cfg.h:70
const char * db_host
Definition: cfg.h:69