BIND: Automatically create the subdirectories leading up to zonefiles (#2397)

This commit is contained in:
Tom Limoncelli 2023-05-26 13:16:20 -04:00 committed by GitHub
parent 3492b26d0a
commit 207ed695cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 3 deletions

View file

@ -96,7 +96,6 @@ The filenameformat is a string with a few printf-like `%` verbs:
* `%%` `%`
* ordinary characters (not `%`) are copied unchanged to the output stream
* FYI: format strings must not end with an incomplete `%` or `%?`
* FYI: `/` or other filesystem separators result in undefined behavior
Typical values:
@ -116,6 +115,12 @@ a different `directory` setting. Otherwise `dnscontrol` will write
both domains to the same file, flapping between the two back and
forth.
(new in v4.2.0) `dnscontrol push` will create subdirectories along the path to
the filename. This includes both the portion of the path created by the
`directory` setting and the `filenameformat` setting. The automatic creation of
subdirectories is disabled if `dnscontrol` is running as root for security
reasons.
# FYI: get-zones
The DNSControl `get-zones all` subcommand scans the directory for

View file

@ -156,7 +156,7 @@ func (c *bindProvider) ListZones() ([]string, error) {
func (c *bindProvider) GetZoneRecords(domain string, meta map[string]string) (models.Records, error) {
if _, err := os.Stat(c.directory); os.IsNotExist(err) {
printer.Printf("\nWARNING: BIND directory %q does not exist!\n", c.directory)
printer.Printf("\nWARNING: BIND directory %q does not exist! (will create)\n", c.directory)
}
if c.zonefile == "" {
@ -312,7 +312,11 @@ func (c *bindProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundR
Msg: msg,
F: func() error {
printer.Printf("WRITING ZONEFILE: %v\n", c.zonefile)
zf, err := os.Create(c.zonefile)
fname, err := preprocessFilename(c.zonefile)
if err != nil {
return fmt.Errorf("could not create zonefile: %w", err)
}
zf, err := os.Create(fname)
if err != nil {
return fmt.Errorf("could not create zonefile: %w", err)
}
@ -335,3 +339,21 @@ func (c *bindProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, foundR
return corrections, nil
}
// preprocessFilename pre-processes a filename we're about to os.Create()
// * On Windows systems, it translates the seperator.
// * It attempts to mkdir the directories leading up to the filename.
// * If running on Linux as root, it does not attempt to create directories.
func preprocessFilename(name string) (string, error) {
universalName := filepath.FromSlash(name)
// Running as root? Don't create the parent directories. It is unsafe.
if os.Getuid() != 0 {
// Create the parent directories
dir := filepath.Dir(name)
universalDir := filepath.FromSlash(dir)
if err := os.MkdirAll(universalDir, 0750); err != nil {
return "", err
}
}
return universalName, nil
}