1 /* $NetBSD: zkt-conf.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */ 2 3 /***************************************************************** 4 ** 5 ** @(#) zkt-conf.c (c) Jan 2005 / Jan 2010 Holger Zuleger hznet.de 6 ** 7 ** A config file utility for the DNSSEC Zone Key Tool 8 ** 9 ** Copyright (c) 2005 - 2008, Holger Zuleger HZnet. All rights reserved. 10 ** 11 ** This software is open source. 12 ** 13 ** Redistribution and use in source and binary forms, with or without 14 ** modification, are permitted provided that the following conditions 15 ** are met: 16 ** 17 ** Redistributions of source code must retain the above copyright notice, 18 ** this list of conditions and the following disclaimer. 19 ** 20 ** Redistributions in binary form must reproduce the above copyright notice, 21 ** this list of conditions and the following disclaimer in the documentation 22 ** and/or other materials provided with the distribution. 23 ** 24 ** Neither the name of Holger Zuleger HZnet nor the names of its contributors may 25 ** be used to endorse or promote products derived from this software without 26 ** specific prior written permission. 27 ** 28 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 32 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 ** POSSIBILITY OF SUCH DAMAGE. 39 ** 40 *****************************************************************/ 41 42 # include <stdio.h> 43 # include <stdlib.h> /* abort(), exit(), ... */ 44 # include <string.h> 45 # include <dirent.h> 46 # include <assert.h> 47 # include <unistd.h> 48 # include <ctype.h> 49 # include <time.h> 50 51 #ifdef HAVE_CONFIG_H 52 # include <config.h> 53 #endif 54 # include "config_zkt.h" 55 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG 56 # include <getopt.h> 57 #endif 58 59 # include "debug.h" 60 # include "misc.h" 61 # include "zfparse.h" 62 # include "zconf.h" 63 64 extern int optopt; 65 extern int opterr; 66 extern int optind; 67 extern char *optarg; 68 const char *progname; 69 70 static const char *view = ""; 71 static int writeflag = 0; 72 static int allflag = 0; 73 static int testflag = 0; 74 75 # define short_options ":aC:c:O:dlstvwV:rh" 76 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG 77 static struct option long_options[] = { 78 {"compability", required_argument, NULL, 'C'}, 79 {"config", required_argument, NULL, 'c'}, 80 {"option", required_argument, NULL, 'O'}, 81 {"config-option", required_argument, NULL, 'O'}, 82 {"default", no_argument, NULL, 'd'}, 83 {"sidecfg", no_argument, NULL, 's'}, 84 {"localcfg", no_argument, NULL, 'l'}, 85 {"all-values", no_argument, NULL, 'a'}, 86 {"test", no_argument, NULL, 't'}, 87 {"overwrite", no_argument, NULL, 'w'}, 88 {"version", no_argument, NULL, 'v' }, 89 {"write", no_argument, NULL, 'w'}, 90 {"view", required_argument, NULL, 'V' }, 91 {"help", no_argument, NULL, 'h'}, 92 {0, 0, 0, 0} 93 }; 94 #endif 95 96 static void usage (char *mesg); 97 98 99 int main (int argc, char *argv[]) 100 { 101 int c; 102 int opt_index; 103 int major = 0; 104 int minor = 0; 105 int revision = 0; 106 const char *file; 107 const char *defconfname = NULL; 108 const char *confname = NULL; 109 char *p; 110 char str[254+1]; 111 zconf_t *refconfig = NULL; 112 zconf_t *config; 113 114 progname = *argv; 115 if ( (p = strrchr (progname, '/')) ) 116 progname = ++p; 117 view = getnameappendix (progname, "zkt-conf"); 118 119 defconfname = getdefconfname (view); 120 dbg_val0 ("Load built in config\n"); 121 config = loadconfig ("", (zconf_t *)NULL); /* load built in config */ 122 123 if ( fileexist (defconfname) ) /* load default config file */ 124 { 125 dbg_val ("Load site wide config file \"%s\"\n", defconfname); 126 config = loadconfig (defconfname, config); 127 } 128 if ( config == NULL ) 129 fatal ("Out of memory\n"); 130 confname = defconfname; 131 132 opterr = 0; 133 opt_index = 0; 134 135 /* set current config version based on ZKT version */ 136 switch ( sscanf (ZKT_VERSION, "%d.%d.%d", &major, &minor, &revision) ) 137 { 138 case 3: major = (major * 100) + (minor * 10) + revision; break; 139 case 2: major = (major * 100) + (minor * 10); break; 140 case 1: major = major * 100; break; 141 default: 142 usage ("illegal release number"); 143 } 144 setconfigversion (major); 145 146 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG 147 while ( (c = getopt_long (argc, argv, short_options, long_options, &opt_index)) != -1 ) 148 #else 149 while ( (c = getopt (argc, argv, short_options)) != -1 ) 150 #endif 151 { 152 switch ( c ) 153 { 154 case 'V': /* view name */ 155 view = optarg; 156 defconfname = getdefconfname (view); 157 if ( fileexist (defconfname) ) /* load default config file */ 158 config = loadconfig (defconfname, config); 159 if ( config == NULL ) 160 fatal ("Out of memory\n"); 161 confname = defconfname; 162 break; 163 case 'O': /* read option from commandline */ 164 config = loadconfig_fromstr (optarg, config); 165 break; 166 case 'C': 167 switch ( sscanf (optarg, "%d.%d.%d", &major, &minor, &revision) ) 168 { 169 case 3: major = (major * 100) + (minor * 10) + revision; break; 170 case 2: major = (major * 100) + (minor * 10); break; 171 case 1: major = major * 100; break; 172 default: 173 usage ("illegal release number"); 174 } 175 setconfigversion (major); 176 break; 177 case 'c': 178 if ( *optarg == '\0' ) 179 usage ("empty config file name"); 180 config = loadconfig (optarg, config); 181 if ( *optarg == '-' || strcmp (optarg, "stdin") == 0 ) 182 confname = "stdout"; 183 else 184 confname = optarg; 185 break; 186 case 'd': /* built-in default config */ 187 config = loadconfig ("", config); /* load built-in config */ 188 confname = defconfname; 189 break; 190 case 's': /* side wide config */ 191 /* this is the default **/ 192 break; 193 case 'a': /* set all flag */ 194 allflag = 1; 195 break; 196 case 'l': /* local config file */ 197 refconfig = dupconfig (config); /* duplicate current config */ 198 confname = LOCALCONF_FILE; 199 if ( fileexist (LOCALCONF_FILE) ) /* try to load local config file */ 200 { 201 dbg_val ("Load local config file \"%s\"\n", LOCALCONF_FILE); 202 config = loadconfig (LOCALCONF_FILE, config); 203 } 204 else if ( !writeflag ) 205 usage ("error: no local config file found"); 206 break; 207 case 't': /* test config */ 208 testflag = 1; 209 break; 210 case 'v': /* version */ 211 fprintf (stderr, "%s version %s compiled for BIND version %d\n", 212 progname, ZKT_VERSION, BIND_VERSION); 213 fprintf (stderr, "ZKT %s\n", ZKT_COPYRIGHT); 214 return 0; 215 break; 216 case 'w': /* write back conf file */ 217 writeflag = 1; 218 break; 219 case 'h': /* print help */ 220 usage (""); 221 break; 222 case ':': 223 snprintf (str, sizeof(str), "option \"-%c\" requires an argument.", 224 optopt); 225 usage (str); 226 break; 227 case '?': 228 if ( isprint (optopt) ) 229 snprintf (str, sizeof(str), "Unknown option \"-%c\".", 230 optopt); 231 else 232 snprintf (str, sizeof (str), "Unknown option char \\x%x.", 233 optopt); 234 usage (str); 235 break; 236 default: 237 abort(); 238 } 239 } 240 241 c = optind; 242 if ( c >= argc ) /* no arguments given on commandline */ 243 { 244 if ( testflag ) 245 { 246 if ( checkconfig (config) ) 247 fprintf (stderr, "All config file parameter seems to be ok\n"); 248 } 249 else 250 { 251 if ( !writeflag ) /* print to stdout */ 252 confname = "stdout"; 253 254 if ( refconfig ) /* have we seen a local config file ? */ 255 if ( allflag ) 256 printconfig (confname, config); 257 else 258 printconfigdiff (confname, refconfig, config); 259 else 260 printconfig (confname, config); 261 } 262 } 263 else /* command line argument found: use it as name of zone file */ 264 { 265 char includefiles[1023+1]; /* list of include files */ 266 size_t filelistsize; /* size of list */ 267 long minttl; 268 long maxttl; 269 int keydbfound; 270 char *dnskeydb; 271 272 file = argv[c++]; 273 274 dnskeydb = config->keyfile; 275 276 minttl = 0x7FFFFFFF; 277 maxttl = 0; 278 includefiles[0] = '\0'; 279 filelistsize = sizeof (includefiles); 280 keydbfound = parsezonefile (file, &minttl, &maxttl, dnskeydb, includefiles, &filelistsize); 281 if ( keydbfound < 0 ) 282 error ("can't parse zone file %s\n", file); 283 284 if ( dnskeydb && !keydbfound ) 285 { 286 if ( writeflag ) 287 { 288 addkeydb (file, dnskeydb); 289 printf ("\"$INCLUDE %s\" directive added to \"%s\"\n", dnskeydb, file); 290 } 291 else 292 printf ("\"$INCLUDE %s\" should be added to \"%s\" (run with option -w)\n", 293 dnskeydb, file); 294 } 295 296 if ( isflistdelim (*includefiles) ) 297 { 298 printf ("InclFiles:\t\"%s\"\n", includefiles+1); 299 } 300 301 if ( minttl < (10 * MINSEC) ) 302 fprintf (stderr, "MinimumTTL of %s (%ld seconds) is too low to use it in a signed zone (see RFC4641)\n", 303 timeint2str (minttl), minttl); 304 else 305 fprintf (stderr, "MinimumTTL:\t%s\t# (%ld seconds)\n", timeint2str (minttl), minttl); 306 fprintf (stdout, "MaximumTTL:\t%s\t# (%ld seconds)\n", timeint2str (maxttl), maxttl); 307 308 if ( writeflag ) 309 { 310 refconfig = dupconfig (config); /* duplicate current config */ 311 confname = LOCALCONF_FILE; 312 if ( fileexist (LOCALCONF_FILE) ) /* try to load local config file */ 313 { 314 dbg_val ("Load local config file \"%s\"\n", LOCALCONF_FILE); 315 config = loadconfig (LOCALCONF_FILE, config); 316 } 317 setconfigpar (config, "MaximumTTL", &maxttl); 318 printconfigdiff (confname, refconfig, config); 319 } 320 } 321 322 323 return 0; 324 } 325 326 # define sopt_usage(mesg, value) fprintf (stderr, mesg, value) 327 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG 328 # define lopt_usage(mesg, value) fprintf (stderr, mesg, value) 329 # define loptstr(lstr, sstr) lstr 330 #else 331 # define lopt_usage(mesg, value) 332 # define loptstr(lstr, sstr) sstr 333 #endif 334 static void usage (char *mesg) 335 { 336 fprintf (stderr, "%s version %s\n", progname, ZKT_VERSION); 337 if ( mesg && *mesg ) 338 fprintf (stderr, "%s\n", mesg); 339 fprintf (stderr, "\n"); 340 fprintf (stderr, "usage: %s -h\n", progname); 341 fprintf (stderr, "usage: %s [-V view] [-w|-t] -d [-O <optstr>]\n", progname); 342 fprintf (stderr, "usage: %s [-V view] [-w|-t] [-s] [-c config] [-O <optstr>]\n", progname); 343 fprintf (stderr, "usage: %s [-V view] [-w|-t] [-a] -l [-c config] [-O <optstr>]\n", progname); 344 fprintf (stderr, "\n"); 345 fprintf (stderr, "usage: %s [-c config] [-w] <zonefile>\n", progname); 346 fprintf (stderr, "\n"); 347 fprintf (stderr, " -V name%s", loptstr (", --view=name\n", "")); 348 fprintf (stderr, "\t\t specify the view name \n"); 349 fprintf (stderr, " -d%s\tprint built-in default config parameter\n", loptstr (", --default", "")); 350 fprintf (stderr, " -s%s\tprint site wide config file parameter (this is the default)\n", loptstr (", --sitecfg", "")); 351 fprintf (stderr, " -l%s\tprint local config file parameter\n", loptstr (", --localcfg", "")); 352 fprintf (stderr, " -a%s\tprint all parameter not only the different one\n", loptstr (", --all", "")); 353 fprintf (stderr, " -c file%s", loptstr (", --config=file\n", "")); 354 fprintf (stderr, " \t\tread config from <file> instead of %s\n", CONFIG_FILE); 355 fprintf (stderr, " -O optstr%s", loptstr (", --config-option=\"optstr\"\n", "")); 356 fprintf (stderr, " \t\tread config options from commandline\n"); 357 fprintf (stderr, " -t%s\ttest the config parameter if they are useful \n", loptstr (", --test", "\t")); 358 fprintf (stderr, " -w%s\twrite or rewrite config file \n", loptstr (", --write", "\t")); 359 fprintf (stderr, " -h%s\tprint this help \n", loptstr (", --help", "\t")); 360 exit (1); 361 } 362 363