OpenDNSSEC-enforcer  2.1.5
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 "locks.h"
41 #include "enforcer/autostart_cmd.h"
42 #include "parser/confparser.h"
43 
44 #define AUTHOR_NAME "Matthijs Mekking, Yuri Schaeffer, RenĂ© Post"
45 #define COPYRIGHT_STR "Copyright (C) 2010-2011 NLnet Labs OpenDNSSEC"
46 
47 static const char* enforcerd_str = "engine";
48 
53 static void
54 usage(FILE* out)
55 {
56  fprintf(out, "Usage: %s [OPTIONS]\n", "ods-enforcerd");
57  fprintf(out, "Start the OpenDNSSEC key and signing policy enforcer "
58  "daemon.\n\n");
59  fprintf(out, "Supported options:\n");
60  fprintf(out, " -c | --config <cfgfile> Read configuration from file.\n");
61  fprintf(out, " -d | --no-daemon Do not daemonize the enforcer "
62  "engine.\n");
63  fprintf(out, " -1 | --single-run Run once, then exit.\n");
64  fprintf(out, " -h | --help Show this help and exit.\n");
65  fprintf(out, " -i | --info Print configuration and exit.\n");
66  fprintf(out, " -v | --verbose Increase verbosity.\n");
67  fprintf(out, " -V | --version Show version and exit.\n");
68  fprintf(out, " --set-time <time> Start daemon at specific time. "
69  "Notation \"YYYY-MM-DD-HH:MM:SS\" or seconds since Unix epoch.\n");
70  fprintf(out, "\nBSD licensed, see LICENSE in source package for "
71  "details.\n");
72  fprintf(out, "Version %s. Report bugs to <%s>.\n",
73  PACKAGE_VERSION, PACKAGE_BUGREPORT);
74 }
75 
76 
81 static void
82 version(FILE* out)
83 {
84  fprintf(out, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
85  fprintf(out, "Written by %s.\n\n", AUTHOR_NAME);
86  fprintf(out, "%s. This is free software.\n", COPYRIGHT_STR);
87  fprintf(out, "See source files for more license information\n");
88  exit(0);
89 }
90 
91 static void
92 program_setup(const char* cfgfile, int cmdline_verbosity)
93 {
94  const char* file;
95  /* fully initialized log with parameters in conf file*/
96  file = parse_conf_log_filename(cfgfile);
97  ods_log_init("ods-enforcerd", parse_conf_use_syslog(cfgfile), file, cmdline_verbosity?cmdline_verbosity:parse_conf_verbosity(cfgfile));
98  ods_log_verbose("[%s] starting enforcer", enforcerd_str);
99 
100  /* initialize */
101  xmlInitGlobals();
102  xmlInitParser();
103  xmlInitThreads();
104 
105  /* setup */
106  tzset(); /* for portability */
107  free((void*)file);
108 }
109 
110 static void
111 program_teardown()
112 {
113  ods_log_close();
114 
115  xmlCleanupParser();
116  xmlCleanupGlobals();
117 }
118 
123 int
124 main(int argc, char* argv[])
125 {
126  char* argv0;
127  ods_status status;
128  engine_type *engine;
129  engineconfig_type* cfg;
130  int returncode;
131  int c;
132  int options_index = 0;
133  int info = 0;
134  int single_run = 0;
135  int daemonize = 1;
136  int cmdline_verbosity = 0;
137  char *time_arg = NULL;
138  const char* cfgfile = ODS_SE_CFGFILE;
139  static struct option long_options[] = {
140  {"single-run", no_argument, 0, '1'},
141  {"config", required_argument, 0, 'c'},
142  {"no-daemon", no_argument, 0, 'd'},
143  {"help", no_argument, 0, 'h'},
144  {"info", no_argument, 0, 'i'},
145  {"verbose", no_argument, 0, 'v'},
146  {"version", no_argument, 0, 'V'},
147  {"set-time", required_argument, 0, 256},
148  { 0, 0, 0, 0}
149  };
150 
151  if(argv[0][0] != '/') {
152  char *path = getcwd(NULL,0);
153  asprintf(&argv0, "%s/%s", path, argv[0]);
154  free(path);
155  } else {
156  argv0 = strdup(argv[0]);
157  }
158 
159  /* parse the commandline */
160  while ((c=getopt_long(argc, argv, "1c:dhivV",
161  long_options, &options_index)) != -1) {
162  switch (c) {
163  case '1':
164  single_run = 1;
165  break;
166  case 'c':
167  cfgfile = optarg;
168  break;
169  case 'd':
170  daemonize = 0;
171  break;
172  case 'h':
173  usage(stdout);
174  exit(0);
175  case 'i':
176  info = 1;
177  break;
178  case 'v':
179  cmdline_verbosity++;
180  break;
181  case 'V':
182  version(stdout);
183  exit(0);
184  case 256:
185  time_arg = optarg;
186  break;
187  default:
188  usage(stderr);
189  exit(2);
190  }
191  }
192  argc -= optind;
193  argv += optind;
194  if (argc != 0) {
195  usage(stderr);
196  exit(2);
197  }
198 
199  if (time_arg) {
200  if(set_time_now_str(time_arg)) {
201  fprintf(stderr, "Error: Failed to interpret start time argument. Daemon not started.\n");
202  return 1;
203  }
204  }
205 
206  /* main stuff */
207  fprintf(stdout, "OpenDNSSEC key and signing policy enforcer version %s\n",
208  PACKAGE_VERSION);
209 
210  ods_janitor_initialize(argv0);
211  program_setup(cfgfile, cmdline_verbosity); /* setup basic logging, xml, PB */
212  engine = engine_alloc(); /* Let's create an engine only once */
213  if (!engine) {
214  ods_log_crit("Could not start engine");
215  program_teardown();
216  return 1;
217  }
218  engine_init(engine, daemonize);
219 
220  returncode = 0;
221  while (!engine->need_to_exit) {
222  /* Parse config file */
223  cfg = engine_config(cfgfile, cmdline_verbosity, engine->config);
224  /* does it make sense? */
225  if (engine_config_check(cfg) != ODS_STATUS_OK) {
226  /* it does not, do we have a previous config loaded? */
227  /*
228  * We can not recover since hsm_open tries to parse
229  * this file as well, in the future we need to use
230  * hsm_open2
231  *
232  * if (engine->config) {
233  ods_log_error("[%s] cfgfile %s has errors, continuing"
234  " with old config", enforcerd_str, cfgfile);
235  } else {*/
236  ods_log_crit("[%s] cfgfile %s has errors", enforcerd_str, cfgfile);
237  returncode = 2;
238  engine_config_cleanup(cfg); /* antagonist of engine_config() */
239  break;
240  /*}*/
241  } else {
242  engine_config_cleanup(engine->config); /* antagonist of engine_config() */
243  engine->config = cfg;
244  }
245 
246  /* Print config and exit */
247  if (info) {
248  engine_config_print(stdout, engine->config); /* for debugging */
249  break;
250  }
251 
252  /* do daemon housekeeping: pid, privdrop, fork, log */
253  if ((status = engine_setup()) != ODS_STATUS_OK) {
254  ods_log_error("setup failed: %s", ods_status2str(status));
255  if (!daemonize)
256  fprintf(stderr, "setup failed: %s\n", ods_status2str(status));
257  returncode = 3;
258  engine->need_to_exit = 1;
259  } else {
260  if (engine_run(engine, autostart, single_run)) {
261  returncode = 4;
262  engine->need_to_exit = 1;
263  }
264  engine_teardown(engine); /* antagonist of engine_setup() */
265  }
266  if (!engine->need_to_exit)
267  ods_log_info("[%s] enforcer reloading", enforcerd_str);
268  }
269  engine_config_cleanup(engine->config);
270  ods_log_info("[engine] enforcer shutdown"); /* needed for test */
271  ods_log_info("[%s] enforcerd (pid: %lu) stopped with exitcode %d",
272  enforcerd_str, (unsigned long) engine->pid, returncode);
273  engine_dealloc(engine); /* antagonist of engine_alloc() */
274  if (returncode && daemonize) {
275  fprintf(stderr, "enforcerd stopped with exitcode %d\n",
276  returncode);
277  }
278  program_teardown(); /* antagonist of program_setup() */
279  return returncode;
280 }
engine_config_cleanup
void engine_config_cleanup(engineconfig_type *config)
Definition: cfg.c:278
AUTHOR_NAME
#define AUTHOR_NAME
Definition: ods-enforcerd.c:44
engine_struct::pid
pid_t pid
Definition: engine.h:50
autostart_cmd.h
argv0
char * argv0
Definition: ods-migrate.c:47
engineconfig_struct
Definition: cfg.h:54
engine_init
void engine_init(engine_type *engine, int daemonize)
Definition: engine.c:613
COPYRIGHT_STR
#define COPYRIGHT_STR
Definition: ods-enforcerd.c:45
engine_config_print
void engine_config_print(FILE *out, engineconfig_type *config)
Definition: cfg.c:189
engine_config_check
ods_status engine_config_check(engineconfig_type *config)
Definition: cfg.c:155
engine_struct::need_to_exit
int need_to_exit
Definition: engine.h:55
engine_setup
ods_status engine_setup()
Definition: engine.c:432
main
int main(int argc, char *argv[])
Definition: ods-enforcerd.c:124
engine_struct
Definition: engine.h:47
autostart
void autostart(engine_type *engine)
Definition: autostart_cmd.c:45
engine_teardown
void engine_teardown(engine_type *engine)
Definition: engine.c:585
engine_struct::config
engineconfig_type * config
Definition: engine.h:48
confparser.h
parse_conf_verbosity
int parse_conf_verbosity(const char *cfgfile)
Definition: confparser.c:617
engine_run
int engine_run(engine_type *engine, start_cb_t start, int single_run)
Definition: engine.c:644
parse_conf_log_filename
const char * parse_conf_log_filename(const char *cfgfile)
Definition: confparser.c:364
engine.h
parse_conf_use_syslog
int parse_conf_use_syslog(const char *cfgfile)
Definition: confparser.c:604
engine_alloc
engine_type * engine_alloc(void)
Definition: engine.c:79
engine_dealloc
void engine_dealloc(engine_type *engine)
Definition: engine.c:97
engine_config
engineconfig_type * engine_config(const char *cfgfile, int cmdline_verbosity, engineconfig_type *oldcfg)
Definition: cfg.c:59