OpenDNSSEC-enforcer  2.0.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 }
71 
72 static void version(FILE* out) {
73  fprintf(out,
74  "Database setup tool for %s version %s\n"
75  "Written by %s.\n\n"
76  "%s. This is free software.\n"
77  "See source files for more license information\n",
78  PACKAGE_NAME,
79  PACKAGE_VERSION,
82  exit(0);
83 }
84 
85 static int connect_db(engineconfig_type* cfg) {
86 #if defined(ENFORCER_DATABASE_SQLITE3)
87  if (!cfg->datastore) {
88  return -1;
89  }
90  if (db) {
91  return -1;
92  }
93 
94  if (sqlite3_initialize() != SQLITE_OK) {
95  return -1;
96  }
97 
98  if (sqlite3_open_v2(cfg->datastore, &db,
99  SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_CREATE,
100  NULL) != SQLITE_OK)
101  {
102  return -1;
103  }
104 
105  return 0;
106 #elif defined(ENFORCER_DATABASE_MYSQL)
107  if (!cfg->datastore) {
108  return -1;
109  }
110  if (db) {
111  return -1;
112  }
113 
114  if (mysql_library_init(0, NULL, NULL)) {
115  return -1;
116  }
117 
118  if (!(db = mysql_init(NULL))
119  || !mysql_real_connect(db,
120  cfg->db_host,
121  cfg->db_username,
122  cfg->db_password,
123  cfg->datastore,
124  cfg->db_port,
125  NULL,
126  0))
127  {
128  if (db) {
129  mysql_close(db);
130  db = NULL;
131  }
132  return -1;
133  }
134 
135  return 0;
136 #else
137  return -1;
138 #endif
139 }
140 
141 static int disconnect_db() {
142 #if defined(ENFORCER_DATABASE_SQLITE3)
143  if (db) {
144  sqlite3_close(db);
145  db = NULL;
146  }
147 
148  sqlite3_shutdown();
149 
150  return 0;
151 #elif defined(ENFORCER_DATABASE_MYSQL)
152  if (db) {
153  mysql_close(db);
154  db = NULL;
155  }
156 
157  mysql_library_end();
158 
159  return 0;
160 #else
161  return -1;
162 #endif
163 }
164 
165 static int db_do(const char *sql, size_t size) {
166 #if defined(ENFORCER_DATABASE_SQLITE3)
167  sqlite3_stmt* stmt = NULL;
168 
169  if (!db) {
170  return -1;
171  }
172  if (!sql) {
173  return -1;
174  }
175 
176  if (sqlite3_prepare_v2(db, sql, size, &stmt, NULL) != SQLITE_OK
177  || sqlite3_step(stmt) != SQLITE_DONE)
178  {
179  if (stmt) {
180  sqlite3_finalize(stmt);
181  }
182  return -1;
183  }
184  sqlite3_finalize(stmt);
185 
186  return 0;
187 #elif defined(ENFORCER_DATABASE_MYSQL)
188  if (!db) {
189  return -1;
190  }
191  if (!sql) {
192  return -1;
193  }
194 
195  if (mysql_real_query(db, sql, size)) {
196  return -1;
197  }
198 
199  return 0;
200 #else
201  return -1;
202 #endif
203 }
204 
205 static int db_do2(const char** strs) {
206  char sql[4096];
207  char *sqlp;
208  int ret, left, i;
209 
210  for (i = 0; strs[i]; i++) {
211  left = sizeof(sql);
212  sqlp = sql;
213 
214  for (; strs[i]; i++) {
215  if ((ret = snprintf(sqlp, left, "%s", strs[i])) >= left) {
216  return -1;
217  }
218  sqlp += ret;
219  left -= ret;
220  }
221 
222  if (db_do(sql, sizeof(sql) - left)) {
223  return -1;
224  }
225  }
226 
227  return 0;
228 }
229 
230 int main(int argc, char* argv[]) {
231  int c, options_index = 0;
232  static struct option long_options[] = {
233  {"help", no_argument, 0, 'h'},
234  {"version", no_argument, 0, 'V'},
235  {"force", no_argument, 0, 'f'},
236  { 0, 0, 0, 0}
237  };
238  int user_certain;
239  int force = 0;
240  engineconfig_type* cfg;
241  const char* cfgfile = ODS_SE_CFGFILE;
242 
243  ods_log_init("ods-enforcerd", 0, NULL, 0);
244 
245  while ((c=getopt_long(argc, argv, "hVf",
246  long_options, &options_index)) != -1) {
247  switch (c) {
248  case 'h':
249  usage(stdout);
250  exit(0);
251  case 'V':
252  version(stdout);
253  exit(0);
254  case 'f':
255  force = 1;
256  break;
257  default:
258  exit(100);
259  }
260  }
261 
262  if (!force) {
263  printf("*WARNING* This will erase all data in the database; "
264  "are you sure? [y/N] ");
265  user_certain = getchar();
266  if (user_certain != 'y' && user_certain != 'Y') {
267  printf("Okay, quitting...\n");
268  return 0;
269  }
270  }
271 
272  cfg = engine_config(cfgfile, 0, NULL);
273  if (engine_config_check(cfg) != ODS_STATUS_OK) {
275  fprintf(stderr, "Error: unable to load configuration!\n");
276  return 1;
277  }
278 
279  if (connect_db(cfg)) {
281  fprintf(stderr, "Error: unable to connect to database!\n");
282  return 2;
283  }
284 
285  /*
286  * Drop existing schema.
287  */
288  if (db_do2(drop)) {
289  fprintf(stderr, "Error: unable to drop existing schema!\n");
290  disconnect_db();
291  return 3;
292  }
293 
294  /*
295  * Create new schema.
296  */
297  if (db_do2(create)) {
298  fprintf(stderr, "Error: unable to create schema!\n");
299  disconnect_db();
300  return 4;
301  }
302 
303  /*
304  * Insert initial data.
305  */
306  if (db_do2(data)) {
307  fprintf(stderr, "Error: unable to insert initial data!\n");
308  disconnect_db();
309  return 5;
310  }
311 
313  printf("Database setup successfully.\n");
314  return 0;
315 }
void engine_config_cleanup(engineconfig_type *config)
Definition: cfg.c:276
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
void(* usage)(int sockfd)
Definition: cmdhandler.h:61
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:153
const char * db_schema_sqlite_drop[]