OpenDNSSEC-enforcer  2.0.2
ods-enforcerd.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
32 #include "config.h"
33 
34 #include <getopt.h>
35 #include <libxml/parser.h>
36 
37 #include "daemon/engine.h"
38 #include "log.h"
39 #include "duration.h"
40 #include "enforcer/autostart_cmd.h"
41 
42 #define AUTHOR_NAME "Matthijs Mekking, Yuri Schaeffer, RenĂ© Post"
43 #define COPYRIGHT_STR "Copyright (C) 2010-2011 NLnet Labs OpenDNSSEC"
44 
45 static const char* enforcerd_str = "engine";
46 
51 static void
52 usage(FILE* out)
53 {
54  fprintf(out, "Usage: %s [OPTIONS]\n", "ods-enforcerd");
55  fprintf(out, "Start the OpenDNSSEC key and signing policy enforcer "
56  "daemon.\n\n");
57  fprintf(out, "Supported options:\n");
58  fprintf(out, " -c | --config <cfgfile> Read configuration from file.\n");
59  fprintf(out, " -d | --no-daemon Do not daemonize the enforcer "
60  "engine.\n");
61  fprintf(out, " -1 | --single-run Run once, then exit.\n");
62  fprintf(out, " -h | --help Show this help and exit.\n");
63  fprintf(out, " -i | --info Print configuration and exit.\n");
64  fprintf(out, " -v | --verbose Increase verbosity.\n");
65  fprintf(out, " -V | --version Show version and exit.\n");
66  fprintf(out, " --set-time <time> Start daemon at specific time. "
67  "Notation \"YYYY-MM-DD-HH:MM:SS\" or seconds since Unix epoch.\n");
68  fprintf(out, "\nBSD licensed, see LICENSE in source package for "
69  "details.\n");
70  fprintf(out, "Version %s. Report bugs to <%s>.\n",
71  PACKAGE_VERSION, PACKAGE_BUGREPORT);
72 }
73 
74 
79 static void
80 version(FILE* out)
81 {
82  fprintf(out, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
83  fprintf(out, "Written by %s.\n\n", AUTHOR_NAME);
84  fprintf(out, "%s. This is free software.\n", COPYRIGHT_STR);
85  fprintf(out, "See source files for more license information\n");
86  exit(0);
87 }
88 
89 static void
90 program_setup(int cmdline_verbosity)
91 {
92  /* for now just log to stderr */
93  ods_log_init("ods-enforcerd", 0, NULL, cmdline_verbosity);
94  ods_log_verbose("[%s] starting enforcer", enforcerd_str);
95 
96  /* initialize */
97  xmlInitGlobals();
98  xmlInitParser();
99  xmlInitThreads();
100 
101  /* setup */
102  tzset(); /* for portability */
103 }
104 
105 static void
106 program_teardown()
107 {
108  ods_log_close();
109 
110  xmlCleanupParser();
111  xmlCleanupGlobals();
112  xmlCleanupThreads();
113 }
114 
119 int
120 main(int argc, char* argv[])
121 {
122  ods_status status;
123  engine_type *engine;
124  engineconfig_type* cfg;
125  int returncode;
126  int c;
127  int options_index = 0;
128  int info = 0;
129  int single_run = 0;
130  int daemonize = 1;
131  int cmdline_verbosity = 0;
132  char *time_arg = NULL;
133  const char* cfgfile = ODS_SE_CFGFILE;
134  static struct option long_options[] = {
135  {"single-run", no_argument, 0, '1'},
136  {"config", required_argument, 0, 'c'},
137  {"no-daemon", no_argument, 0, 'd'},
138  {"help", no_argument, 0, 'h'},
139  {"info", no_argument, 0, 'i'},
140  {"verbose", no_argument, 0, 'v'},
141  {"version", no_argument, 0, 'V'},
142  {"set-time", required_argument, 0, 256},
143  { 0, 0, 0, 0}
144  };
145 
146  /* parse the commandline */
147  while ((c=getopt_long(argc, argv, "1c:dhivV",
148  long_options, &options_index)) != -1) {
149  switch (c) {
150  case '1':
151  single_run = 1;
152  break;
153  case 'c':
154  cfgfile = optarg;
155  break;
156  case 'd':
157  daemonize = 0;
158  break;
159  case 'h':
160  usage(stdout);
161  exit(0);
162  case 'i':
163  info = 1;
164  break;
165  case 'v':
166  cmdline_verbosity++;
167  break;
168  case 'V':
169  version(stdout);
170  exit(0);
171  case 256:
172  time_arg = optarg;
173  break;
174  default:
175  usage(stderr);
176  exit(2);
177  }
178  }
179  argc -= optind;
180  argv += optind;
181  if (argc != 0) {
182  usage(stderr);
183  exit(2);
184  }
185 
186  if (time_arg) {
187  if(set_time_now_str(time_arg)) {
188  fprintf(stderr, "Error: Failed to interpret start time argument. Daemon not started.\n");
189  return 1;
190  }
191  }
192 
193  /* main stuff */
194  fprintf(stdout, "OpenDNSSEC key and signing policy enforcer version %s\n",
195  PACKAGE_VERSION);
196 
197  program_setup(cmdline_verbosity); /* setup basic logging, xml, PB */
198  engine = engine_alloc(); /* Let's create an engine only once */
199  if (!engine) {
200  ods_log_crit("Could not start engine");
201  program_teardown();
202  return 1;
203  }
204  engine_init(engine, daemonize);
205 
206  returncode = 0;
207  while (!engine->need_to_exit) {
208  /* Parse config file */
209  cfg = engine_config(cfgfile, cmdline_verbosity, engine->config);
210  /* does it make sense? */
211  if (engine_config_check(cfg) != ODS_STATUS_OK) {
212  /* it does not, do we have a previous config loaded? */
213  /*
214  * We can not recover since hsm_open tries to parse
215  * this file as well, in the future we need to use
216  * hsm_open2
217  *
218  * if (engine->config) {
219  ods_log_error("[%s] cfgfile %s has errors, continuing"
220  " with old config", enforcerd_str, cfgfile);
221  } else {*/
222  ods_log_crit("[%s] cfgfile %s has errors", enforcerd_str, cfgfile);
223  returncode = 2;
224  engine_config_cleanup(cfg); /* antagonist of engine_config() */
225  break;
226  /*}*/
227  } else {
228  engine_config_cleanup(engine->config); /* antagonist of engine_config() */
229  engine->config = cfg;
230  }
231 
232  /* Print config and exit */
233  if (info) {
234  engine_config_print(stdout, engine->config); /* for debugging */
235  break;
236  }
237 
238  /* do daemon housekeeping: pid, privdrop, fork, log */
239  if ((status = engine_setup(engine)) != ODS_STATUS_OK) {
240  ods_log_error("setup failed: %s", ods_status2str(status));
241  if (!daemonize)
242  fprintf(stderr, "setup failed: %s\n", ods_status2str(status));
243  returncode = 3;
244  engine->need_to_exit = 1;
245  } else {
246  if (engine_run(engine, autostart, single_run)) {
247  returncode = 4;
248  engine->need_to_exit = 1;
249  }
250  engine_teardown(engine); /* antagonist of engine_setup() */
251  }
252  if (!engine->need_to_exit)
253  ods_log_info("[%s] enforcer reloading", enforcerd_str);
254  }
255  engine_config_cleanup(engine->config);
256  ods_log_info("[engine] enforcer shutdown"); /* needed for test */
257  ods_log_info("[%s] enforcerd (pid: %lu) stopped with exitcode %d",
258  enforcerd_str, (unsigned long) engine->pid, returncode);
259  engine_dealloc(engine); /* antagonist of engine_alloc() */
260  if (returncode && daemonize) {
261  fprintf(stderr, "enforcerd stopped with exitcode %d\n",
262  returncode);
263  }
264  program_teardown(); /* antagonist of program_setup() */
265  return returncode;
266 }
void engine_config_cleanup(engineconfig_type *config)
Definition: cfg.c:276
void engine_config_print(FILE *out, engineconfig_type *config)
Definition: cfg.c:187
void engine_teardown(engine_type *engine)
Definition: engine.c:550
#define AUTHOR_NAME
Definition: ods-enforcerd.c:42
engineconfig_type * engine_config(const char *cfgfile, int cmdline_verbosity, engineconfig_type *oldcfg)
Definition: cfg.c:59
ods_status engine_setup(engine_type *engine)
Definition: engine.c:443
void ods_log_info(const char *format,...)
Definition: log.c:55
void autostart(engine_type *engine)
Definition: autostart_cmd.c:44
void ods_log_error(const char *format,...)
Definition: log.c:69
int engine_run(engine_type *engine, start_cb_t start, int single_run)
Definition: engine.c:609
#define COPYRIGHT_STR
Definition: ods-enforcerd.c:43
void ods_log_crit(const char *format,...)
Definition: log.c:80
engineconfig_type * config
Definition: engine.h:53
void engine_init(engine_type *engine, int daemonize)
Definition: engine.c:578
engine_type * engine_alloc(void)
Definition: engine.c:76
pid_t pid
Definition: engine.h:60
int main(int argc, char *argv[])
void ods_log_verbose(const char *format,...)
Definition: log.c:48
ods_status engine_config_check(engineconfig_type *config)
Definition: cfg.c:153
int need_to_exit
Definition: engine.h:65
void engine_dealloc(engine_type *engine)
Definition: engine.c:96