492 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			492 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			PHP
		
	
	
	
<?php
 | 
						|
 | 
						|
 | 
						|
class system_bind {
 | 
						|
    var $ZONE_TEMPLATE ="/etc/alternc/templates/bind/templates/zone.template";
 | 
						|
    var $NAMED_TEMPLATE ="/etc/alternc/templates/bind/templates/named.template";
 | 
						|
    var $NAMED_CONF ="/var/lib/alternc/bind/automatic.conf";
 | 
						|
    var $RNDC ="/usr/sbin/rndc";
 | 
						|
 | 
						|
    var $dkim_trusted_host_file = "/etc/opendkim/TrustedHosts";
 | 
						|
    var $dkim_keytable_file = "/etc/opendkim/KeyTable";
 | 
						|
    var $dkim_signingtable_file = "/etc/opendkim/SigningTable";
 | 
						|
 | 
						|
    var $cache_conf_db = array();
 | 
						|
    var $cache_get_persistent = array();
 | 
						|
    var $cache_zone_file = array();
 | 
						|
    var $cache_domain_summary = array();
 | 
						|
    var $zone_file_directory = '/var/lib/alternc/bind/zones/';
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     */
 | 
						|
    function system_bind() {
 | 
						|
        // Constructeur
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the part of the conf we got from the database
 | 
						|
     * 
 | 
						|
     * @global m_mysql $db
 | 
						|
     * @param string $domain
 | 
						|
     * @return array $this->cache_conf_db
 | 
						|
     */
 | 
						|
    function conf_from_db($domain=false) {
 | 
						|
        global $db;
 | 
						|
        // Use cache, fill cache if empty
 | 
						|
        if (empty($this->cache_conf_db)) {
 | 
						|
            $db->query("
 | 
						|
        select 
 | 
						|
          sd.domaine, 
 | 
						|
          replace(replace(dt.entry,'%TARGET%',sd.valeur), '%SUB%', if(length(sd.sub)>0,sd.sub,'@')) as entry 
 | 
						|
        from 
 | 
						|
          sub_domaines sd,
 | 
						|
          domaines_type dt 
 | 
						|
        where 
 | 
						|
          sd.type=dt.name 
 | 
						|
          and sd.enable in ('ENABLE', 'ENABLED') 
 | 
						|
        order by entry ;");
 | 
						|
            $t=array();
 | 
						|
            while ($db->next_record()) {
 | 
						|
                $t[$db->f('domaine')][] = $db->f('entry');
 | 
						|
            }
 | 
						|
            $this->cache_conf_db = $t;
 | 
						|
        }
 | 
						|
        if ($domain) {
 | 
						|
            if (isset($this->cache_conf_db[$domain])) {
 | 
						|
                return $this->cache_conf_db[$domain];
 | 
						|
            } else {
 | 
						|
                return array();
 | 
						|
            }
 | 
						|
        } // if domain
 | 
						|
        return $this->cache_conf_db;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return full path of the zone configuration file
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    function get_zone_file_uri($domain) {
 | 
						|
        return $this->zone_file_directory.$domain;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return string zone file path
 | 
						|
     */
 | 
						|
    function get_zone_file($domain) {
 | 
						|
        // Use cache, fill cache if empty
 | 
						|
        if (!isset($this->cache_zone_file[$domain]) ) {
 | 
						|
            if (file_exists($this->get_zone_file_uri($domain))) {
 | 
						|
                $this->cache_zone_file[$domain] = @file_get_contents($this->get_zone_file_uri($domain));
 | 
						|
            } else {
 | 
						|
                $this->cache_zone_file[$domain] = false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return $this->cache_zone_file[$domain] ;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return string 
 | 
						|
     */
 | 
						|
    function get_serial($domain) {
 | 
						|
        // Return the next serial the domain must have.
 | 
						|
        // Choose between a generated and an incremented.
 | 
						|
    
 | 
						|
        // Calculated :
 | 
						|
        $calc = date('Ymd').'00'."\n";
 | 
						|
 | 
						|
        // Old one :
 | 
						|
        $old=$calc; // default value
 | 
						|
        $file = $this->get_zone_file($domain);
 | 
						|
        preg_match_all("/\s*(\d{10})\s+\;\sserial\s?/", $file, $output_array);
 | 
						|
        if (isset($output_array[1][0]) && !empty($output_array[1][0])) {
 | 
						|
            $old = $output_array[1][0];
 | 
						|
        }
 | 
						|
 | 
						|
        // Return max between newly calculated, and old one incremented
 | 
						|
        return max(array($calc,$old)) + 1 ;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return lines that are after ;;; END ALTERNC AUTOGENERATE CONFIGURATION
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    function get_persistent($domain) {
 | 
						|
        if ( ! isset($this->cache_get_persistent[$domain] )) {
 | 
						|
            preg_match_all('/\;\s*END\sALTERNC\sAUTOGENERATE\sCONFIGURATION(.*)/s', $this->get_zone_file($domain), $output_array);
 | 
						|
            if (isset($output_array[1][0]) && !empty($output_array[1][0])) {
 | 
						|
                $this->cache_get_persistent[$domain] = $output_array[1][0];
 | 
						|
            } else {
 | 
						|
                $this->cache_get_persistent[$domain] = false;
 | 
						|
            }
 | 
						|
        } // isset
 | 
						|
        return $this->cache_get_persistent[$domain];
 | 
						|
    }
 | 
						|
  
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @return string 
 | 
						|
     */
 | 
						|
    function get_zone_header() {
 | 
						|
        return file_get_contents($this->ZONE_TEMPLATE);
 | 
						|
    }
 | 
						|
  
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @global m_dom $dom
 | 
						|
     * @param string $domain
 | 
						|
     * @return array Retourne un tableau 
 | 
						|
     */
 | 
						|
    function get_domain_summary($domain=false) {
 | 
						|
        global $dom;
 | 
						|
 | 
						|
        // Use cache if is filled, if not, fill it
 | 
						|
        if (empty($this->cache_domain_summary)) {
 | 
						|
            $this->cache_domain_summary = $dom->get_domain_all_summary();
 | 
						|
        }
 | 
						|
 | 
						|
        if ($domain) return $this->cache_domain_summary[$domain];
 | 
						|
        else return $this->cache_domain_summary;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return boolean
 | 
						|
     */
 | 
						|
    function dkim_delete($domain) {
 | 
						|
        $target_dir = "/etc/opendkim/keys/$domain";
 | 
						|
        if (file_exists($target_dir)) {
 | 
						|
            @unlink("$target_dir/alternc_private");
 | 
						|
            @unlink("$target_dir/alternc.txt");
 | 
						|
            @rmdir($target_dir);
 | 
						|
        }
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Generate the domain DKIM key
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return null|boolean
 | 
						|
     */
 | 
						|
    function dkim_generate_key($domain) {
 | 
						|
        // Stop here if we do not manage the mail
 | 
						|
        $domainInfo = $this->get_domain_summary($domain);
 | 
						|
        if ( !  $domainInfo['gesmx'] ) return;
 | 
						|
 | 
						|
        $target_dir = "/etc/opendkim/keys/$domain";
 | 
						|
 | 
						|
        if (file_exists($target_dir.'/alternc.txt')) return; // Do not generate if exist
 | 
						|
 | 
						|
        if (! is_dir($target_dir)) mkdir($target_dir); // create dir
 | 
						|
 | 
						|
        // Generate the key
 | 
						|
        $old_dir=getcwd();
 | 
						|
        chdir($target_dir);
 | 
						|
        exec('opendkim-genkey -r -d '.escapeshellarg($domain).' -s "alternc" ');
 | 
						|
        chdir($old_dir);
 | 
						|
 | 
						|
        // opendkim must be owner of the key
 | 
						|
        chown("$target_dir/alternc.private", 'opendkim');
 | 
						|
        chgrp("$target_dir/alternc.private", 'opendkim');
 | 
						|
 | 
						|
        return true; // FIXME handle error
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Refresh DKIM configuration: be sure to list the domain having a private key (and only them)
 | 
						|
     */
 | 
						|
    function dkim_refresh_list() { 
 | 
						|
        // so ugly... but there is only 1 pass, not 3. Still ugly.
 | 
						|
        $trusted_host_new = "# WARNING: this file is auto generated by AlternC.\n# Add your changes after the last line\n";
 | 
						|
        $keytable_new     = "# WARNING: this file is auto generated by AlternC.\n# Add your changes after the last line\n";
 | 
						|
        $signingtable_new = "# WARNING: this file is auto generated by AlternC.\n# Add your changes after the last line\n";
 | 
						|
 | 
						|
        # Generate automatic entry
 | 
						|
        foreach ($this->get_domain_summary() as $domain => $ds ) {
 | 
						|
            // Skip if delete in progress, or if we do not manage dns or mail
 | 
						|
            if ( ! $ds['gesdns'] || ! $ds['gesmx'] || strtoupper($ds['dns_action']) == 'DELETE' ) continue;
 | 
						|
 | 
						|
            // Skip if there is no key generated
 | 
						|
            if (! file_exists("/etc/opendkim/keys/$domain/alternc.txt")) continue; 
 | 
						|
 | 
						|
            // Modif the files.
 | 
						|
            $trusted_host_new.="$domain\n";
 | 
						|
            $keytable_new    .="alternc._domainkey.$domain $domain:alternc:/etc/opendkim/keys/$domain/alternc.private\n";
 | 
						|
            $signingtable_new.="$domain alternc._domainkey.$domain\n";
 | 
						|
        }
 | 
						|
        $trusted_host_new.="# END AUTOMATIC FILE. ADD YOUR CHANGES AFTER THIS LINE\n";
 | 
						|
        $keytable_new    .="# END AUTOMATIC FILE. ADD YOUR CHANGES AFTER THIS LINE\n";
 | 
						|
        $signingtable_new.="# END AUTOMATIC FILE. ADD YOUR CHANGES AFTER THIS LINE\n";
 | 
						|
 | 
						|
        # Get old files
 | 
						|
        $trusted_host_old=@file_get_contents($this->dkim_trusted_host_file);
 | 
						|
        $keytable_old    =@file_get_contents($this->dkim_keytable_file);
 | 
						|
        $signingtable_old=@file_get_contents($this->dkim_signingtable_file);
 | 
						|
    
 | 
						|
        # Keep manuel entry
 | 
						|
        preg_match_all('/\#\s*END\ AUTOMATIC\ FILE\.\ ADD\ YOUR\ CHANGES\ AFTER\ THIS\ LINE(.*)/s', $trusted_host_old, $output_array);
 | 
						|
        if (isset($output_array[1][0]) && !empty($output_array[1][0])) {
 | 
						|
            $trusted_host_new.=$output_array[1][0];
 | 
						|
        } 
 | 
						|
        preg_match_all('/\#\s*END\ AUTOMATIC\ FILE\.\ ADD\ YOUR\ CHANGES\ AFTER\ THIS\ LINE(.*)/s', $keytable_old, $output_array);
 | 
						|
        if (isset($output_array[1][0]) && !empty($output_array[1][0])) {
 | 
						|
            $keytable_new.=$output_array[1][0];
 | 
						|
        } 
 | 
						|
        preg_match_all('/\#\s*END\ AUTOMATIC\ FILE\.\ ADD\ YOUR\ CHANGES\ AFTER\ THIS\ LINE(.*)/s', $signingtable_old, $output_array);
 | 
						|
        if (isset($output_array[1][0]) && !empty($output_array[1][0])) {
 | 
						|
            $signingtable_new.=$output_array[1][0];
 | 
						|
        } 
 | 
						|
    
 | 
						|
        // Save if there are some diff
 | 
						|
        if ( $trusted_host_new != $trusted_host_old ) {
 | 
						|
            file_put_contents($this->dkim_trusted_host_file, $trusted_host_new);
 | 
						|
        }
 | 
						|
        if ( $keytable_new != $keytable_old ) {
 | 
						|
            file_put_contents($this->dkim_keytable_file, $keytable_new);
 | 
						|
        }
 | 
						|
        if ( $signingtable_new != $signingtable_old ) {
 | 
						|
            file_put_contents($this->dkim_signingtable_file, $signingtable_new);
 | 
						|
        }
 | 
						|
 | 
						|
    }
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    function dkim_entry($domain) {
 | 
						|
        $keyfile="/etc/opendkim/keys/$domain/alternc.txt";
 | 
						|
        $domainInfo         = $this->get_domain_summary($domain);
 | 
						|
        if (! file_exists($keyfile) &&  $domainInfo['gesmx'] ) {
 | 
						|
            $this->dkim_generate_key($domain);
 | 
						|
        }
 | 
						|
        return @file_get_contents($keyfile);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Conditionnal generation autoconfig entry for outlook / thunderbird
 | 
						|
     * If entry with the same name allready exist, skip it.
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    function mail_autoconfig_entry($domain) {
 | 
						|
        $zone= implode("\n",$this->conf_from_db($domain))."\n".$this->get_persistent($domain);
 | 
						|
 | 
						|
        $entry='';
 | 
						|
        $domainInfo                 = $this->get_domain_summary($domain);
 | 
						|
        if ( $domainInfo['gesmx'] ) {
 | 
						|
            // If we manage the mail
 | 
						|
 | 
						|
            // Check if there is no the same entry (defined or manual)
 | 
						|
            // can be toto IN A or toto.fqdn.tld. IN A
 | 
						|
            if (! preg_match("/autoconfig(\s|\.".str_replace('.','\.',$domain)."\.)/", $zone )) {
 | 
						|
                $entry.="autoconfig IN CNAME %%fqdn%%.\n";
 | 
						|
            }
 | 
						|
            if (! preg_match("/autodiscover(\s|\.".str_replace('.','\.',$domain)."\.)/", $zone )) {
 | 
						|
                $entry.="autodiscover IN CNAME %%fqdn%%.\n";
 | 
						|
            }
 | 
						|
        } // if gesmx
 | 
						|
        return $entry;
 | 
						|
    }
 | 
						|
  
 | 
						|
  
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * Return a fully generated zone
 | 
						|
     * 
 | 
						|
     * @global string $L_FQDN
 | 
						|
     * @global string $L_NS1_HOSTNAME
 | 
						|
     * @global string $L_NS2_HOSTNAME
 | 
						|
     * @global string $L_DEFAULT_MX
 | 
						|
     * @global string $L_DEFAULT_SECONDARY_MX
 | 
						|
     * @global string $L_PUBLIC_IP
 | 
						|
     * @param string $domain
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    function get_zone($domain) {
 | 
						|
        global $L_FQDN, $L_NS1_HOSTNAME, $L_NS2_HOSTNAME, $L_DEFAULT_MX, $L_DEFAULT_SECONDARY_MX, $L_PUBLIC_IP;
 | 
						|
 | 
						|
        $zone =$this->get_zone_header();
 | 
						|
        $zone.=implode("\n",$this->conf_from_db($domain));
 | 
						|
        $zone.="\n;;;HOOKED ENTRY\n";
 | 
						|
 | 
						|
        $zone.= $this->dkim_entry($domain);
 | 
						|
        $zone.= $this->mail_autoconfig_entry($domain);
 | 
						|
 | 
						|
        $zone.="\n;;; END ALTERNC AUTOGENERATE CONFIGURATION\n";
 | 
						|
        $zone.=$this->get_persistent($domain);
 | 
						|
        $domainInfo = $this->get_domain_summary($domain);
 | 
						|
 | 
						|
        // FIXME check those vars
 | 
						|
        $zone = strtr($zone, array(
 | 
						|
            "%%fqdn%%"=>"$L_FQDN",
 | 
						|
            "%%ns1%%"=>"$L_NS1_HOSTNAME",
 | 
						|
            "%%ns2%%"=>"$L_NS2_HOSTNAME",
 | 
						|
            "%%DEFAULT_MX%%"=>"$L_DEFAULT_MX",
 | 
						|
            "%%DEFAULT_SECONDARY_MX%%"=>"$L_DEFAULT_SECONDARY_MX",
 | 
						|
            "@@fqdn@@"=>"$L_FQDN",
 | 
						|
            "@@ns1@@"=>"$L_NS1_HOSTNAME",
 | 
						|
            "@@ns2@@"=>"$L_NS2_HOSTNAME",
 | 
						|
            "@@DEFAULT_MX@@"=>"$L_DEFAULT_MX",
 | 
						|
            "@@DEFAULT_SECONDARY_MX@@"=>"$L_DEFAULT_SECONDARY_MX",
 | 
						|
            "@@DOMAINE@@"=>"$domain",
 | 
						|
            "@@SERIAL@@"=>$this->get_serial($domain),
 | 
						|
            "@@PUBLIC_IP@@"=>"$L_PUBLIC_IP",
 | 
						|
            "@@ZONETTL@@"=> $domainInfo['zonettl'],
 | 
						|
        ));
 | 
						|
 | 
						|
        return $zone;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     */
 | 
						|
    function reload_zone($domain) {
 | 
						|
        exec($this->RNDC." reload ".escapeshellarg($domain), $output, $return_value);
 | 
						|
        if ($return_value != 0 ) {
 | 
						|
            echo "ERROR: Reload zone failed for zone $domain\n";
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * return true if zone is locked
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return boolean
 | 
						|
     */
 | 
						|
    function is_locked($domain) {
 | 
						|
        preg_match_all("/(\;\s*LOCKED:YES)/i", $this->get_zone_file($domain), $output_array);
 | 
						|
        if (isset($output_array[1][0]) && !empty($output_array[1][0])) {
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        return false;
 | 
						|
    }  
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @global m_mysql $db
 | 
						|
     * @global m_dom $dom
 | 
						|
     * @param string $domain
 | 
						|
     * @return boolean
 | 
						|
     */
 | 
						|
    function save_zone($domain) {
 | 
						|
        global $db, $dom;
 | 
						|
 | 
						|
        // Do not save if the zone is LOCKED
 | 
						|
        if ( $this->is_locked($domain)) {
 | 
						|
            $dom->set_dns_result($domain, "The zone file of this domain is locked. Contact your administrator."); // If edit, change dummy_for_translation
 | 
						|
            $dom->set_dns_action($domain, 'OK');
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 
 | 
						|
        // Save file, and apply chmod/chown
 | 
						|
        $file=$this->get_zone_file_uri($domain);
 | 
						|
        file_put_contents($file, $this->get_zone($domain));
 | 
						|
        chown($file, 'bind');
 | 
						|
        chmod($file, 0640);
 | 
						|
 | 
						|
        $dom->set_dns_action($domain, 'OK');
 | 
						|
        return true; // fixme add tests
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Delete the zone configuration file
 | 
						|
     * 
 | 
						|
     * @param string $domain
 | 
						|
     * @return boolean
 | 
						|
     */
 | 
						|
    function delete_zone($domain) {
 | 
						|
        $file=$this->get_zone_file_uri($domain);
 | 
						|
        if (file_exists($file)) {
 | 
						|
            unlink($file);
 | 
						|
        }
 | 
						|
        $this->dkim_delete($domain);
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @global m_hooks $hooks
 | 
						|
     * @return boolean
 | 
						|
     */
 | 
						|
    function reload_named() {
 | 
						|
        global $hooks;
 | 
						|
        // Generate the new conf file
 | 
						|
        $new_named_conf="// DO NOT EDIT\n// This file is generated by Alternc.\n// Every changes you'll make will be overwrited.\n";
 | 
						|
        $tpl=file_get_contents($this->NAMED_TEMPLATE);
 | 
						|
        foreach ($this->get_domain_summary() as $domain => $ds ) {
 | 
						|
            if ( ! $ds['gesdns'] || strtoupper($ds['dns_action']) == 'DELETE' ) continue;
 | 
						|
            $new_named_conf.=strtr($tpl, array("@@DOMAINE@@"=>$domain, "@@ZONE_FILE@@"=>$this->get_zone_file_uri($domain)));
 | 
						|
        }
 | 
						|
 | 
						|
        // Get the actual conf file
 | 
						|
        $old_named_conf = @file_get_contents($this->NAMED_CONF);
 | 
						|
 | 
						|
        // Apply new configuration only if there are some differences
 | 
						|
        if ($old_named_conf != $new_named_conf ) {
 | 
						|
            file_put_contents($this->NAMED_CONF,$new_named_conf);
 | 
						|
            chown($this->NAMED_CONF, 'bind');
 | 
						|
            chmod($this->NAMED_CONF, 0640);
 | 
						|
            exec($this->RNDC." reconfig");
 | 
						|
            $hooks->invoke_scripts("/usr/lib/alternc/reload.d", array('dns_reconfig')  );
 | 
						|
        }
 | 
						|
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Regenerate bind configuration and load it
 | 
						|
     * 
 | 
						|
     * @global m_hooks $hooks
 | 
						|
     * @param boolean $all
 | 
						|
     * @return boolean
 | 
						|
     */
 | 
						|
    function regenerate_conf($all=false) {
 | 
						|
        global $hooks;
 | 
						|
 | 
						|
        foreach ($this->get_domain_summary() as $domain => $ds ) {
 | 
						|
            if ( ! $ds['gesdns'] && strtoupper($ds['dns_action']) == 'OK' ) continue; // Skip if we do not manage DNS and is up-to-date for this domain
 | 
						|
 | 
						|
            if ( (strtoupper($ds['dns_action']) == 'DELETE' ) || 
 | 
						|
            (strtoupper($ds['dns_action']) == 'UPDATE' && $ds['gesdns']==false ) // in case we update the zone to disable DNS management
 | 
						|
            ) { 
 | 
						|
                $this->delete_zone($domain);
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
 | 
						|
            if ( ( $all || strtoupper($ds['dns_action']) == 'UPDATE' ) && $ds['gesdns'] ) {
 | 
						|
                $this->save_zone($domain);
 | 
						|
                $this->reload_zone($domain);
 | 
						|
                $hooks->invoke_scripts("/usr/lib/alternc/reload.d", array('dns_reload_zone', $domain)  );
 | 
						|
            }
 | 
						|
        } // end foreach domain
 | 
						|
 | 
						|
        $this->dkim_refresh_list();
 | 
						|
        $this->reload_named();
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     */
 | 
						|
    private function dummy_for_translation() {
 | 
						|
        _("The zone file of this domain is locked. Contact your administrator.");
 | 
						|
    }
 | 
						|
 | 
						|
} // class
 | 
						|
 | 
						|
 | 
						|
?>
 |