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