2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 01:59:26 +00:00

Enable named-checkzone and named-compilezone to take input from stdin

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
This commit is contained in:
Diego Fronza 2019-11-07 15:28:42 -03:00
parent 121e9ddf97
commit 63c88f4a04
5 changed files with 85 additions and 14 deletions

View 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));
}

View 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);
}

View 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);
/*%<

View 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

View 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;