]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Enable named-checkzone and named-compilezone to take input from stdin
authorDiego Fronza <diego@isc.org>
Thu, 7 Nov 2019 18:28:42 +0000 (15:28 -0300)
committerDiego Fronza <diego@isc.org>
Thu, 20 Feb 2020 14:19:13 +0000 (11:19 -0300)
If a filename (the last argument) is not provided for named-checkzone or
named-compilezone, or if it is a single dash "-" character,
zone data will be read from stdin.

Example of invocation:
cat /etc/zone_name.db | named-compilezone -f text -F raw \
    -o zone_name.raw zone_name

bin/check/check-tool.c
bin/check/named-checkzone.c
lib/dns/include/dns/zone.h
lib/dns/win32/libdns.def.in
lib/dns/zone.c

index 5f00121d2665b911003e952f0aff9b00cc8ac1c1..38387b172b9bd6652334e468bfeaa32bf7fc6b61 100644 (file)
@@ -695,8 +695,13 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
        CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL));
        CHECK(dns_zone_setorigin(zone, origin));
        dns_zone_setdbtype(zone, 1, (const char *const *)dbtype);
-       CHECK(dns_zone_setfile(zone, filename, fileformat,
-                              &dns_master_style_default));
+       if (strcmp(filename, "-") == 0) {
+               CHECK(dns_zone_setstream(zone, stdin, fileformat,
+                                        &dns_master_style_default));
+       } else {
+               CHECK(dns_zone_setfile(zone, filename, fileformat,
+                                      &dns_master_style_default));
+       }
        if (journal != NULL) {
                CHECK(dns_zone_setjournal(zone, journal));
        }
index e50f84e0d2fde176ea77cef36eaacdff8710c47a..4b15bd02b2d4aa28494d1bfac59f652bfa34e7d3 100644 (file)
@@ -18,6 +18,7 @@
 #include <isc/app.h>
 #include <isc/commandline.h>
 #include <isc/dir.h>
+#include <isc/file.h>
 #include <isc/hash.h>
 #include <isc/log.h>
 #include <isc/mem.h>
@@ -76,7 +77,7 @@ usage(void) {
                "[-i (full|full-sibling|local|local-sibling|none)] "
                "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] "
                "[-W (ignore|warn)] "
-               "%s zonename filename\n",
+               "%s zonename [ (filename|-) ]\n",
                prog_name,
                progmode == progmode_check ? "[-o filename]" : "-o filename");
        exit(1);
@@ -94,7 +95,7 @@ int
 main(int argc, char **argv) {
        int c;
        char *origin = NULL;
-       char *filename = NULL;
+       const char *filename = NULL;
        isc_log_t *lctx = NULL;
        isc_result_t result;
        char classname_in[] = "IN";
@@ -512,7 +513,8 @@ main(int argc, char **argv) {
                logdump = false;
        }
 
-       if (isc_commandline_index + 2 != argc) {
+       if (argc - isc_commandline_index < 1 ||
+           argc - isc_commandline_index > 2) {
                usage();
        }
 
@@ -529,7 +531,16 @@ main(int argc, char **argv) {
        dns_result_register();
 
        origin = argv[isc_commandline_index++];
-       filename = argv[isc_commandline_index++];
+
+       if (isc_commandline_index == argc) {
+               /* "-" will be interpreted as stdin */
+               filename = "-";
+       } else {
+               filename = argv[isc_commandline_index];
+       }
+
+       isc_commandline_index++;
+
        result = load_zone(mctx, origin, filename, inputformat, classname,
                           maxttl, &zone);
 
@@ -563,5 +574,6 @@ main(int argc, char **argv) {
 #ifdef _WIN32
        DestroySockets();
 #endif /* ifdef _WIN32 */
+
        return ((result == ISC_R_SUCCESS) ? 0 : 1);
 }
index f209e95bf037ec728dddfc2687c58d80d8183435..80ccb229794aaaa59074b4314f1a54ac8d97be8c 100644 (file)
@@ -295,6 +295,23 @@ dns_zone_getfile(dns_zone_t *zone);
  *\li  Pointer to null-terminated file name, or NULL.
  */
 
+isc_result_t
+dns_zone_setstream(dns_zone_t *zone, const FILE *stream,
+                  dns_masterformat_t format, const dns_master_style_t *style);
+/*%<
+ *    Sets the source stream from which the zone will load its database.
+ *
+ * Requires:
+ *\li  'zone' to be a valid zone.
+ *\li  'stream' to be a valid and open FILE *.
+ *\li  'zone->masterfile' to be NULL, since we should load data either from
+ *     'stream' or from a master file, but not both.
+ *
+ * Returns:
+ *\li  #ISC_R_NOMEMORY
+ *\li  #ISC_R_SUCCESS
+ */
+
 void
 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t records);
 /*%<
index 83d750cb0341d0c0c0a079bd6956877efa6c7125..38ee1a123a5cd5eea3bfcb6f238ac0cd63020b58 100644 (file)
@@ -1351,6 +1351,7 @@ dns_zone_setssutable
 dns_zone_setstatistics
 dns_zone_setstatlevel
 dns_zone_setstats
+dns_zone_setstream
 dns_zone_settask
 dns_zone_settype
 dns_zone_setupdateacl
index a7d11e8192f3026b7ee76aafdaa019304a670990..b0161c3311ed86916b601e2ffa8ec073dbc243f9 100644 (file)
@@ -214,6 +214,7 @@ struct dns_zone {
        isc_refcount_t irefs;
        dns_name_t origin;
        char *masterfile;
+       const FILE *stream;                  /* loading from a stream? */
        ISC_LIST(dns_include_t) includes;    /* Include files */
        ISC_LIST(dns_include_t) newincludes; /* Loading */
        unsigned int nincludes;
@@ -986,6 +987,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        zone->strrdclass = NULL;
        zone->strviewname = NULL;
        zone->masterfile = NULL;
+       zone->stream = NULL;
        ISC_LIST_INIT(zone->includes);
        ISC_LIST_INIT(zone->newincludes);
        zone->nincludes = 0;
@@ -1672,6 +1674,7 @@ dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format,
        isc_result_t result = ISC_R_SUCCESS;
 
        REQUIRE(DNS_ZONE_VALID(zone));
+       REQUIRE(zone->stream == NULL);
 
        LOCK_ZONE(zone);
        result = dns_zone_setstring(zone, &zone->masterfile, file);
@@ -1694,6 +1697,27 @@ dns_zone_getfile(dns_zone_t *zone) {
        return (zone->masterfile);
 }
 
+isc_result_t
+dns_zone_setstream(dns_zone_t *zone, const FILE *stream,
+                  dns_masterformat_t format, const dns_master_style_t *style) {
+       isc_result_t result = ISC_R_SUCCESS;
+
+       REQUIRE(DNS_ZONE_VALID(zone));
+       REQUIRE(stream != NULL);
+       REQUIRE(zone->masterfile == NULL);
+
+       LOCK_ZONE(zone);
+       zone->stream = stream;
+       zone->masterformat = format;
+       if (format == dns_masterformat_text) {
+               zone->masterstyle = style;
+       }
+       result = default_journal(zone);
+       UNLOCK_ZONE(zone);
+
+       return (result);
+}
+
 dns_ttl_t
 dns_zone_getmaxttl(dns_zone_t *zone) {
        REQUIRE(DNS_ZONE_VALID(zone));
@@ -2175,8 +2199,10 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
             (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
            rbt)
        {
-               if (zone->masterfile == NULL ||
-                   !isc_file_exists(zone->masterfile)) {
+               if (zone->stream == NULL &&
+                   (zone->masterfile == NULL ||
+                    !isc_file_exists(zone->masterfile)))
+               {
                        if (zone->masterfile != NULL) {
                                dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
                                              ISC_LOG_DEBUG(1),
@@ -2221,7 +2247,7 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
        }
 
        if (!dns_db_ispersistent(db)) {
-               if (zone->masterfile != NULL) {
+               if (zone->masterfile != NULL || zone->stream != NULL) {
                        result = zone_startload(db, zone, loadtime);
                } else {
                        result = DNS_R_NOMASTERFILE;
@@ -2643,11 +2669,21 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
                        zone_idetach(&callbacks.zone);
                        return (result);
                }
-               result = dns_master_loadfile(
-                       zone->masterfile, &zone->origin, &zone->origin,
-                       zone->rdclass, options, 0, &callbacks,
-                       zone_registerinclude, zone, zone->mctx,
-                       zone->masterformat, zone->maxttl);
+
+               if (zone->stream != NULL) {
+                       FILE *stream = NULL;
+                       DE_CONST(zone->stream, stream);
+                       result = dns_master_loadstream(
+                               stream, &zone->origin, &zone->origin,
+                               zone->rdclass, options, &callbacks, zone->mctx);
+               } else {
+                       result = dns_master_loadfile(
+                               zone->masterfile, &zone->origin, &zone->origin,
+                               zone->rdclass, options, 0, &callbacks,
+                               zone_registerinclude, zone, zone->mctx,
+                               zone->masterformat, zone->maxttl);
+               }
+
                tresult = dns_db_endload(db, &callbacks);
                if (result == ISC_R_SUCCESS) {
                        result = tresult;