chiark / gitweb /
Major overhaul.
[zoneconf] / zoneconf.in
old mode 100755 (executable)
new mode 100644 (file)
similarity index 95%
rename from bin/zoneconf
rename to zoneconf.in
index 772088a..f0dcdef
@@ -1,4 +1,4 @@
-#! /usr/bin/tclsh8.5
+#! @TCLSH@
 ### -*-tcl-*-
 ###
 ### Generate `named.conf' stanze for multiple views.
@@ -981,40 +981,44 @@ define-configuration-space dynamic ZONECFG {
 }
 
 ## Everything about a zone.
+set HOME "@pkgstatedir@"
+set BINDPROGS "@bindprogsdir@"
 define-configuration-space zone ZONECFG {
   define-simple user root
-  define-simple master-dir "/var/lib/bind"
-  define-simple slave-dir "/var/cache/bind"
+  define-simple home-dir $HOME
+  define-simple static-dir "$HOME/static"
+  define-simple dynamic-dir "$HOME/dynamic"
   define-simple dir-mode 2775
   define-simple zone-file "%v/%z.zone"
   define-simple soa-format increment
   define-list views *
   define-list sign-views {}
-  define-list signzone-command {
-    /usr/sbin/dnssec-signzone
-    -g
-    -S
-    -K/var/lib/bind/key
-    -d/var/lib/bind/ds
-    -s-3600 -e+176400
-    -N%q
-    -o%z
-    -f%o
-    %f
-  }
+  define-list signzone-command \
+      [list "$BINDPROGS/dnssec-signzone" \
+          "-g" \
+          "-S" \
+          "-K%h/key" \
+          "-d%h/ds" \
+          "-s-3600" "-e+176400" \
+          "-N%q" \
+          "-o%z" \
+          "-f%o" \
+          "%f"]
   define-simple auto-dnssec off
-  define-list reload-command {/usr/sbin/rndc reload %z IN %v}
-  define-list autosign-command {/usr/sbin/rndc sign %z IN %v}
-  define-list checkzone-command {
-    /usr/sbin/named-checkzone
-    -ifull
-    -kfail
-    -Mfail
-    -nfail
-    -Sfail
-    -Wfail
-    %z
-    %f
+  define-list reload-command [list "$BINDPROGS/rndc" "reload" "%z" "IN" "%v"]
+  define-list autosign-command [list "$BINDPROGS/rndc" "sign" "%z" "IN" "%v"]
+  define-list checkzone-command \
+      [list "$BINDPROGS/named-checkzone" \
+          "-ifull" \
+          "-kfail" \
+          "-Mfail" \
+          "-nfail" \
+          "-Sfail" \
+          "-Wfail" \
+          "%z" "%f"]
+
+  define setvar {name value} {
+    dict set ZONECFG(var) $name $value
   }
 
   define primary {map} {
@@ -1066,7 +1070,7 @@ define-configuration-space toplevel ZONECFG {
   include zone
 
   define-list all-views {}
-  define-simple conf-file "/var/lib/zoneconf/config/%v.conf"
+  define-simple conf-file "$HOME/config/%v.conf"
   define-simple max-zone-size [expr {512*1024}]
   define-list reconfig-command {/usr/sbin/rndc reconfig}
 
@@ -1152,11 +1156,11 @@ proc compute-zone-properties {view config} {
   ## Work out the file names.
   switch -glob -- $zone(config-type):$zone(type) {
     master:static {
-      set dir $zone(master-dir)
+      set dir $zone(static-dir)
       set nameview $zone(mapped-view)
     }
     default {
-      set dir $zone(slave-dir)
+      set dir $zone(dynamic-dir)
       set nameview $view
     }
   }
@@ -1195,10 +1199,10 @@ proc write-ddns-update-policy {prefix chan config} {
     set rrtypes [lrange $item 4 end]
     puts $chan [format $policyskel \
                    $verb \
-                     $ident \
-                     $type \
-                     $name \
-                     $rrtypes]
+                   $ident \
+                   $type \
+                   $name \
+                   $rrtypes]
   }
 
   puts $chan [format $policyskel \
@@ -1211,19 +1215,28 @@ proc write-ddns-update-policy {prefix chan config} {
   puts $chan "${prefix}};"
 }
 
-proc sign-zone-file {info input soafmt} {
+proc sign-zone-file {info soafmt infile} {
   ## Sign the zone described by INFO.  The input zone file is INPUT; the SOA
   ## should be updated according to SOAFMT.
 
   global QUIS
 
   array set zone $info
-  return [run "zone `$zone(name)' in view `$zone(mapped-view)'" \
-             $zone(signzone-command) \
-             "%z" $zone(name) \
-             "%f" $zone(file-name) \
-             "%o" $zone(server-file-name) \
-             "%q" $soafmt]
+  set outfile "$zone(server-file-name).new"
+  if {![run "zone `$zone(name)' in view `$zone(mapped-view)'" \
+           $zone(signzone-command) \
+           "%h" $zone(home-dir) \
+           "%m" $zone(static-dir) \
+           "%s" $zone(dynamic-dir) \
+           "%z" $zone(name) \
+           "%f" $infile \
+           "%o" $outfile \
+           "%q" $soafmt]} {
+    file delete -force $outfile
+    return false
+  }
+  file rename -force $outfile $zone(server-file-name)
+  return true
 }
 
 proc write-zone-stanza {view chan config} {
@@ -1270,7 +1283,7 @@ proc write-zone-stanza {view chan config} {
 ###--------------------------------------------------------------------------
 ### Command-line interface.
 
-set CONFFILE "/etc/bind/zones.in"
+set CONFFILE "@pkgconfdir@/zones.in"
 
 defcmd outputs {} {
   help-text "List the output file names to stdout."
@@ -1316,7 +1329,9 @@ defcmd update {} {
   } {
 
     ## Close the open files.
-    foreach view $ZONECFG(all-views) { close $chan($view) }
+    foreach view $ZONECFG(all-views) {
+      catch { close $chan($view) }
+    }
 
     ## If we succeeded, rename the output files into their proper places;
     ## otherwise, delete them.
@@ -1326,7 +1341,7 @@ defcmd update {} {
       }
       eval exec $ZONECFG(reconfig-command)
     } else {
-      file delete -force -- "$out($view).new"
+      catch { file delete -force -- "$out($view).new" }
     }
   }
 }
@@ -1334,8 +1349,8 @@ defcmd update {} {
 defcmd install {user view name} {
   help-text "Install a new zone file.
 
-The file is for the given zone NAME and \(user-side) VIEW.  The file is
-provided by the named USER"
+           The file is for the given zone NAME and \(user-side) VIEW.  The file is
+           provided by the named USER"
 } {
   global QUIS ZONECFG ZONES CONFFILE errorInfo errorCode
 
@@ -1343,7 +1358,7 @@ provided by the named USER"
   confspc-eval toplevel [list source $CONFFILE]
 
   ## Make sure there's a temporary directory.
-  file mkdir [file join $ZONECFG(master-dir) "tmp"]
+  file mkdir [file join $ZONECFG(home-dir) "tmp"]
 
   ## Keep track of cleanup jobs.
   set cleanup {}
@@ -1374,7 +1389,7 @@ provided by the named USER"
     ## Make a new temporary file to read the zone into.
     set pid [pid]
     for {set i 0} {$i < 1000} {incr i} {
-      set tmp [file join $ZONECFG(master-dir) "tmp" \
+      set tmp [file join $ZONECFG(home-dir) "tmp" \
                   "tmp.$pid.$i.$user.$name"]
       if {![catch { set chan [open $tmp {WRONLY CREAT EXCL}] } msg]} {
        break
@@ -1401,15 +1416,15 @@ provided by the named USER"
 
     ## Check the zone for sanity.
     if {![run "zone check" $zone(checkzone-command) \
-            "%z" $name \
-            "%v" $view \
-            "%f" $tmp]} {
+             "%z" $name \
+             "%v" $view \
+             "%f" $tmp]} {
       eval $cleanup
       exit 1
     }
 
     ## If the zone wants signing, better to do that now.
-    if {![sign-zone-file $matchinfo $tmp keep]} {
+    if {![sign-zone-file $matchinfo keep $tmp]} {
       eval $cleanup
       exit 2
     }
@@ -1459,8 +1474,8 @@ defcmd sign {} {
        ## Sign the zone file if we haven't tried before.
        set id [list $zone(name) $zone(mapped-view)]
        if {![info exists seen($id)]} {
-         if {[sign-zone-file $compinfo \
-                  $zone(file-name) $zone(soa-format)]} {
+         if {[sign-zone-file $compinfo $zone(soa-format) \
+                  $zone(server-file-name)]} {
            set seen($id) true
          } else {
            set rc 2
@@ -1496,7 +1511,7 @@ defcmd sign {} {
 ###--------------------------------------------------------------------------
 ### Main program.
 
-set VERSION "1.0.0"
+set VERSION "@VERSION@"
 set USAGE() " \[-OPTIONS] SUBCOMMAND \[ARGUMENTS...]"
 
 define-options OPTS {