diff --git a/.gitattributes b/.gitattributes index d924bfbf..9505dac3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -391,6 +391,7 @@ bureau/admin/vm.php -text bureau/admin/webmail-redirect.php -text bureau/admin/xhprof_footer.php -text bureau/admin/xhprof_header.php -text +bureau/class/class_system_bind.php -text bureau/class/config.php -text bureau/class/config_nochk.php -text bureau/class/db_mysql.php -text diff --git a/bureau/class/class_system_bind.php b/bureau/class/class_system_bind.php new file mode 100644 index 00000000..9ecbda0a --- /dev/null +++ b/bureau/class/class_system_bind.php @@ -0,0 +1,367 @@ +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 ;"); + 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 + function get_zone_file_uri($domain) { + return $this->zone_file_directory.$domain; + } + + 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] ; + } + + 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 + 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]; + } + + function get_zone_header($domain) { + return file_get_contents($this->ZONE_TEMPLATE); + } + + 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; + } + + 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 + function dkim_generate_key($domain) { + // Stop here if we do not manage the mail + if ( ! $this->get_domain_summary($domain)['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"; + $keytable_new .="# END AUTOMATIC FILE. ADD YOUR CHANGES AFTER THIS LINE"; + $signingtable_new.="# END AUTOMATIC FILE. ADD YOUR CHANGES AFTER THIS LINE"; + + # 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); + } + + } + + function dkim_entry($domain) { + $keyfile="/etc/opendkim/keys/$domain/alternc.txt"; + if (! file_exists($keyfile) && $this->get_domain_summary($domain)['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. + function mail_autoconfig_entry($domain) { + $zone= implode("\n",$this->conf_from_db($domain))."\n".$this->get_persistent($domain); + + $entry=''; + if ( $this->get_domain_summary($domain)['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 + 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($domain); + $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"; + $zone.=$this->get_persistent($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@@"=> $this->get_domain_summary($domain)['zonettl'], + )); + + return $zone; + } + + function reload_zone($domain) { + exec($this->RNDC." reload ".escapeshellarg($domain)); + } + + // return true if zone is locked + function is_locked($domain) { + preg_match_all("/(\;\s*LOCKED:YES)/i", $this->get_zone($domain), $output_array); + if (isset($output_array[1][0]) && !empty($output_array[1][0])) { + return true; + } + return false; + } + + function save_zone($domain) { + global $db; + + // Do not save if the zone is LOCKED + if ( $this->is_locked($domain)) 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); + + $db->query("UPDATE domaines SET dns_action = 'OK' WHERE domaine = '".mysql_escape_string($domain)."';"); + return true; // fixme add tests + } + + // Delete the zone configuration file + function delete_zone($domain) { + $file=$this->get_zone_file_uri($domain); + if (file_exists($file)) { + unlink($file); + } + $this->dkim_delete($domain); + return; + } + + 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 + 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; + } + +} // class + + +?> diff --git a/bureau/class/config.php b/bureau/class/config.php index e42bed21..43b22265 100644 --- a/bureau/class/config.php +++ b/bureau/class/config.php @@ -158,20 +158,25 @@ $cuid=0; $classes=array(); /* CLASSES PHP : automatic include : */ -$c=opendir($root."class/"); -while ($di=readdir($c)) { - if (preg_match("#^m_(.*)\\.php$#",$di,$match)) { // $ - $name1="m_".$match[1]; - $name2=$match[1]; - $classes[]=$name2; - require_once($root."class/".$name1.".php"); +foreach ( glob( $root."class/m_*.php") as $di ) { + if (preg_match("#${root}class/m_(.*)\\.php$#",$di,$match)) { // $ + $name=$match[1]; + $classes[]=$name; + require_once($di); } } -closedir($c); /* THE DEFAULT CLASSES ARE : dom, ftp, mail, quota, bro, admin, mem, mysql, err, variables */ +// Load file for the system class. +// Those class will not be build by default. +// They may contain forbidden action for the panel, for example: exec, system +// or files operations +// We can imagine load those class only for command-line scripts. +foreach ( glob( $root."class/class_system_*.php") as $fcs ) { + if (is_readable($fcs)) require_once($fcs); +} /* Language */ include_once("lang_env.php"); diff --git a/bureau/class/m_dom.php b/bureau/class/m_dom.php index aed9d922..7a4a5586 100644 --- a/bureau/class/m_dom.php +++ b/bureau/class/m_dom.php @@ -1947,8 +1947,6 @@ function generate_conf_oldhook($action, $lst_sub, $sub_obj=null) { system($cmd); } } // foreach $lst_by_type - - } /** diff --git a/bureau/class/m_hooks.php b/bureau/class/m_hooks.php index 83a8c795..f4e181eb 100644 --- a/bureau/class/m_hooks.php +++ b/bureau/class/m_hooks.php @@ -74,5 +74,38 @@ class m_hooks { return $val; } + // $scripts a script or a directory + // invoke each executable script of the directory (or the specified script) + // with the parameters + function invoke_scripts($scripts, $parameters) { + + // First, build the list of script we want to launch + $to_launch=array(); + if (is_file($scripts)) { + if (is_executable($script)) { + $to_launch[]=$scripts; + } + } else if (is_dir($scripts)) { + foreach ( scandir($scripts) as $ccc ) { + if (is_file($ccc) && is_executable($ccc)) { + $to_launch[]=$ccc; + } + } + } else { + // not a file nor a directory + return false; + } + + // Protect each parameters + $parameters = array_map('escapeshellarg', $parameters); + $params = implode(" ", $parameters); + + // Launch ! + foreach($to_launch as $fi) { + system($fi." ".$params); + } + return true; + } + } /* Class hooks */ diff --git a/src/generate_bind_conf.php b/src/generate_bind_conf.php index d392b3fb..c5f6f49c 100755 --- a/src/generate_bind_conf.php +++ b/src/generate_bind_conf.php @@ -13,368 +13,8 @@ require_once("/usr/share/alternc/panel/class/config_nochk.php"); ini_set("display_errors", 1); +$bind = new system_bind(); -class m_bind_regenerate { - 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 m_bind_regenerate() { - // Constructeur - } - - // Return the part of the conf we got from the database - 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 ;"); - 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 - function get_zone_file_uri($domain) { - return $this->zone_file_directory.$domain; - } - - 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] ; - } - - 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 - 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]; - } - - function get_zone_header($domain) { - return file_get_contents($this->ZONE_TEMPLATE); - } - - 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; - } - - 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 - function dkim_generate_key($domain) { - // Stop here if we do not manage the mail - if ( ! $this->get_domain_summary($domain)['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"; - $keytable_new .="# END AUTOMATIC FILE. ADD YOUR CHANGES AFTER THIS LINE"; - $signingtable_new.="# END AUTOMATIC FILE. ADD YOUR CHANGES AFTER THIS LINE"; - - # 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); - } - - } - - function dkim_entry($domain) { - $keyfile="/etc/opendkim/keys/$domain/alternc.txt"; - if (! file_exists($keyfile) && $this->get_domain_summary($domain)['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. - function mail_autoconfig_entry($domain) { - $zone= implode("\n",$this->conf_from_db($domain))."\n".$this->get_persistent($domain); - - $entry=''; - if ( $this->get_domain_summary($domain)['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 - 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($domain); - $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"; - $zone.=$this->get_persistent($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@@"=> $this->get_domain_summary($domain)['zonettl'], - )); - - return $zone; - } - - function reload_zone($domain) { - exec($this->RNDC." reload ".escapeshellarg($domain)); - } - - // return true if zone is locked - function is_locked($domain) { - preg_match_all("/(\;\s*LOCKED:YES)/i", $this->get_zone($domain), $output_array); - if (isset($output_array[1][0]) && !empty($output_array[1][0])) { - return true; - } - return false; - } - - function save_zone($domain) { - global $db; - - // Do not save if the zone is LOCKED - if ( $this->is_locked($domain)) 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, 640); - - $db->query("UPDATE domaines SET dns_action = 'OK' WHERE domaine = '".mysql_escape_string($domain)."';"); - return true; // fixme add tests - } - - // Delete the zone configuration file - function delete_zone($domain) { - $file=$this->get_zone_file_uri($domain); - if (file_exists($file)) { - unlink($file); - } - $this->dkim_delete($domain); - return; - } - - function reload_named() { - // 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, 640); - exec($this->RNDC." reconfig"); - } - } - - // Regenerate bind configuration and load it - function regenerate_conf($all=false) { - 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); - // FIXME reload zone hooks - } - } // end foreach domain - - $this->dkim_refresh_list(); - $this->reload_named(); - // FIXME reload named hooks - - return; - } - -} // class - -$bind = new m_bind_regenerate(); - -$bind->regenerate_conf(true); - -echo "Forced regeneration of DNS: done."; - +//$bind->regenerate_conf(true); // use it to force regeneration +$bind->regenerate_conf(); diff --git a/src/update_domains.sh b/src/update_domains.sh index a66ee07b..41694717 100644 --- a/src/update_domains.sh +++ b/src/update_domains.sh @@ -45,32 +45,7 @@ echo $$ > "$LOCK_FILE" # set sub_domaines.web_action = delete where domaines.dns_action = DELETE mysql_query "update sub_domaines sd, domaines d set sd.web_action = 'DELETE' where sd.domaine = d.domaine and sd.compte=d.compte and d.dns_action = 'DELETE';" -# Domains we do not want to be the DNS serveur anymore : -# domaines.dns_action = UPDATE and domaines.gesdns = 0 -for dom in `mysql_query "select domaine from domaines where dns_action = 'UPDATE' and gesdns = 0;"| tr '\n' ' '` -do - dns_delete $dom - mysql_query "update domaines set dns_action = 'OK', dns_result = '$?' where domaine = '$dom'" -done - -# Domains we have to update the dns : -# domaines.dns_action = UPDATE -for dom in `mysql_query "select domaine from domaines where dns_action = 'UPDATE';" | tr '\n' ' '` -do - echo "dns_regenerate : domain=/$dom/" - dns_regenerate $dom - mysql_query "update domaines set dns_action = 'OK', dns_result = '$?' where domaine = '$dom'" -done - -# Domains we want to delete completely, now we do it -# domaines.dns_action = DELETE -for dom in `mysql_query "select domaine from domaines where dns_action = 'DELETE';" | tr '\n' ' '` -do - dns_delete $dom - # Web configurations have already bean cleaned previously - mysql_query "delete from sub_domaines where domaine='$dom'; delete from domaines where domaine='$dom';" -done - +# Launc apache script. If the script said so, reload apache. if [ $(/usr/lib/alternc/generate_apache_conf.php) -gt 0 ] ; then # We must reload apache @@ -78,15 +53,12 @@ if [ $(/usr/lib/alternc/generate_apache_conf.php) -gt 0 ] ; then /usr/lib/alternc/alternc_reload apache || true # Launch hooks for apache reload + # In this directory, you can add you remote web server control run-parts --arg=web_reload /usr/lib/alternc/reload.d fi -## FIXME : move the slave part into the /usr/lib/alternc/reload.d directory to be an hook -#for slave in $ALTERNC_SLAVES; do -# if [ "$slave" != "localhost" ]; then -# ssh alternc@$slave alternc_reload 'apache' || true -# fi -#done +# Do bind updates +/usr/lib/alternc/generate_bind_conf.php rm -f "$LOCK_FILE" "$RELOAD_ZONES" "$INOTIFY_UPDATE_DOMAIN"