OpenDNSSEC-enforcer  2.1.3
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"
47 static const char** create = db_schema_sqlite_create;
48 static const char** drop = db_schema_sqlite_drop;
49 static const char** data = db_data_sqlite;
50 static 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"
55 static const char** create = db_schema_mysql_create;
56 static const char** drop = db_schema_mysql_drop;
57 static const char** data = db_data_mysql;
58 static 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 
64 static 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 
75 static 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 
88 static 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 
144 static 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 
168 static 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 
208 static 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 
233 int 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;
243  engineconfig_type* cfg;
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 }
void engine_config_cleanup(engineconfig_type *config)
Definition: cfg.c:278
const char * db_schema_sqlite_create[]
const char * datastore
Definition: cfg.h:68
engineconfig_type * engine_config(const char *cfgfile, int cmdline_verbosity, engineconfig_type *oldcfg)
Definition: cfg.c:59
const char * db_host
Definition: cfg.h:69
const char * db_password
Definition: cfg.h:71
const char * db_data_mysql[]
Definition: db_data_mysql.c:29
const char * db_schema_mysql_drop[]
int main(int argc, char *argv[])
const char * db_username
Definition: cfg.h:70
const char * db_schema_mysql_create[]
const char * db_data_sqlite[]
#define COPYRIGHT_STR
#define AUTHOR_NAME
ods_status engine_config_check(engineconfig_type *config)
Definition: cfg.c:155
const char * db_schema_sqlite_drop[]