Merge branch 'feature-updatedomains-php'
This commit is contained in:
commit
b5b8bc3028
|
@ -41,3 +41,4 @@ bureau/locales/fr_FR/LC_MESSAGES/messages.po~
|
|||
bureau/locales/it_IT/LC_MESSAGES/messages.po~
|
||||
bureau/locales/nl_NL/LC_MESSAGES/messages.po~
|
||||
bureau/locales/pt_BR/LC_MESSAGES/messages.po~
|
||||
.tx/alternc.alternc
|
||||
|
|
|
@ -130,8 +130,8 @@ $dom->unlock();
|
|||
|
||||
<select class="inl" name="https_<?php ehe($dt['name']); ?>" id="https_<?php ehe($dt['name']); ?>">
|
||||
<option value="http"<?php selected((strtoupper($type)==strtoupper($dt['name']) && $sd["https"]=="http") || false); ?>><?php __("HTTP Only (redirect HTTPS to HTTP)"); ?></option>
|
||||
<option value="https"<?php selected((strtoupper($type)==strtoupper($dt['name']) && $sd["https"]=="http") || true); ?>><?php __("HTTPS Only (redirect HTTP to HTTPS)"); ?></option>
|
||||
<option value="both"<?php selected((strtoupper($type)==strtoupper($dt['name']) && $sd["https"]=="http") || false); ?>><?php __("Both HTTP and HTTPS hosted at the same place"); ?></option>
|
||||
<option value="https"<?php selected((strtoupper($type)==strtoupper($dt['name']) && $sd["https"]=="https") || true); ?>><?php __("HTTPS Only (redirect HTTP to HTTPS)"); ?></option>
|
||||
<option value="both"<?php selected((strtoupper($type)==strtoupper($dt['name']) && $sd["https"]=="both") || false); ?>><?php __("Both HTTP and HTTPS hosted at the same place"); ?></option>
|
||||
</select>
|
||||
<?php } ?>
|
||||
</td>
|
||||
|
@ -147,7 +147,7 @@ $dom->unlock();
|
|||
}
|
||||
?></button>
|
||||
<?php if ($isedit) { ?>
|
||||
<button class="inb cancel" name="cancel" onclick="document.location = 'dom_edit.php?domain=<?php echo $domain; ?>'"><?php __("Cancel"); ?></button>
|
||||
<button class="inb cancel" type="button" name="cancel" onclick="document.location = 'dom_edit.php?domain=<?php echo $domain; ?>'"><?php __("Cancel"); ?></button>
|
||||
<?php } ?>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -197,7 +197,6 @@ if (!$r["sub"][$i]["only_dns"]) {
|
|||
__("HTTP and HTTPS");
|
||||
break;
|
||||
default:
|
||||
__("Unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ if (!defined("ALTERNC_PANEL")) exit(); // must be included ;)
|
|||
if (file_exists("styles/style-custom.css") ) {
|
||||
echo '<link rel="stylesheet" href="styles/style-custom.css" type="text/css" />';
|
||||
}
|
||||
if (count($addhead['css'])) {
|
||||
if (isset($addhead) && count($addhead['css'])) {
|
||||
foreach($addhead['css'] as $css) echo $css."\n";
|
||||
}
|
||||
$favicon = variable_get('favicon', 'favicon.ico' ,'You can specify a favicon, for example /images/my_logo.ico', array('desc'=>'URL','type'=>'string'));
|
||||
|
@ -53,7 +53,7 @@ $favicon = variable_get('favicon', 'favicon.ico' ,'You can specify a favicon, fo
|
|||
<script src="/javascript/jquery-ui/jquery-ui.min.js" type="text/javascript"></script>
|
||||
<script src="/javascript/jquery-tablesorter/jquery.tablesorter.min.js" type="text/javascript"></script>
|
||||
<?php
|
||||
if (count($addhead['js'])) {
|
||||
if (isset($addhead) && count($addhead['js'])) {
|
||||
foreach($addhead['js'] as $js) echo $js."\n";
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -1,525 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------------
|
||||
LICENSE
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License (GPL)
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
To read the license please visit http://www.gnu.org/copyleft/gpl.html
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* bind9 file management class
|
||||
*
|
||||
* @copyright AlternC-Team 2000-2017 https://alternc.com/
|
||||
*/
|
||||
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/';
|
||||
|
||||
|
||||
/**
|
||||
* 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 system_bind */
|
||||
|
|
@ -242,6 +242,26 @@ class DB_Sql {
|
|||
return $data;
|
||||
}
|
||||
|
||||
/* pdo equivalent of fetch() */
|
||||
function fetch($mode=PDO::FETCH_ASSOC) {
|
||||
if (!$this->pdo_query) {
|
||||
$this->halt("next_record called with no query pending.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$data = $this->pdo_query->fetch($mode);
|
||||
$this->Errno = $this->pdo_query->errorCode();
|
||||
$this->Error = $this->pdo_query->errorInfo();
|
||||
|
||||
if ($data == FALSE) {
|
||||
if ($this->Auto_Free)
|
||||
$this->free();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* table locking
|
||||
*/
|
||||
|
|
|
@ -1245,3 +1245,54 @@ function _dovecot_hash($password) {
|
|||
$hash = _sha512cr($password);
|
||||
return '{SHA512-CRYPT}' . $hash;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Add the line of text $line into file $file.
|
||||
* do not duplicate (check)
|
||||
* @param $file string the full path to the file where we should add the line
|
||||
* @param $line string the line to add (without the termination \n, WILL BE ADDED)
|
||||
* @return boolean TRUE if the line has been added, or FALSE if the line ALREADY EXISTED
|
||||
*/
|
||||
function add_line_to_file($file,$line) {
|
||||
$f=fopen($file,"rb");
|
||||
$found=false;
|
||||
while($s=fgets($f,1024)) {
|
||||
if (trim($s)==$line) {
|
||||
$found=true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fclose($f);
|
||||
$f=fopen($file,"ab");
|
||||
fputs($f,trim($line)."\n");
|
||||
fclose($f);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Remove the line of text $line from file $file.
|
||||
* @param $file string the full path to the file where we should remove the line
|
||||
* @param $line string the line to add (without the termination \n, WILL BE REMOVED)
|
||||
* @return boolean TRUE if the line has been found and removed, or FALSE if the line DIDN'T EXIST
|
||||
*/
|
||||
function del_line_from_file($file,$line) {
|
||||
$f=fopen($file,"rb");
|
||||
$g=fopen($file.".new","wb");
|
||||
$found=false;
|
||||
while($s=fgets($f,1024)) {
|
||||
if (trim($s)!=$line) {
|
||||
fputs($g,$s);
|
||||
} else {
|
||||
$found=true;
|
||||
}
|
||||
}
|
||||
fclose($f);
|
||||
fclose($g);
|
||||
rename($file.".new",$file); // overwrite atomically
|
||||
return $found;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------------
|
||||
LICENSE
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License (GPL)
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
To read the license please visit http://www.gnu.org/copyleft/gpl.html
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages APACHE 2.4+ vhosts templates in AlternC 3.5+
|
||||
*
|
||||
* @copyright AlternC-Team 2000-2018 https://alternc.com/
|
||||
*/
|
||||
class m_apache {
|
||||
|
||||
var $shouldreload;
|
||||
|
||||
// only values allowed for https in subdomaines table.
|
||||
var $httpsmodes=array("http","https","both");
|
||||
|
||||
// Slave AlternC instances can know the last reload time thanks to this
|
||||
var $reloadfile="/run/alternc/apache-reload";
|
||||
// Where do we find apache template files ?
|
||||
var $templatedir="/etc/alternc/templates/apache2";
|
||||
// Where do we store all Apache vhosts ?
|
||||
var $vhostroot="/var/lib/alternc/apache-vhost/";
|
||||
|
||||
// launched before any action by updatedomains
|
||||
function hook_updatedomains_web_pre() {
|
||||
$this->shouldreload=false;
|
||||
}
|
||||
|
||||
// launched for each FQDN for which we want a new vhost template
|
||||
function hook_updatedomains_web_add($subdomid) {
|
||||
global $msg,$db,$ssl,$L_FQDN;
|
||||
|
||||
$db->query("SELECT sd.*, dt.only_dns, dt.has_https_option, m.login FROM domaines_type dt, sub_domaines sd LEFT JOIN membres m ON m.uid=sd.compte WHERE dt.name=sd.type AND sd.web_action!='OK' AND id=?;",array($subdomid));
|
||||
$db->next_record();
|
||||
$subdom=$db->Record;
|
||||
|
||||
// security : only AlternC account's UIDs
|
||||
if ($subdom["compte"]<1999) {
|
||||
$msg->raise("ERROR","apache","Subdom ".$subdom["id"]." for domain ".$subdom["sub"].".".$subdom["domaine"]." has id ".$subdom["compte"].". Skipped");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// search for the template file:
|
||||
$template = $this->templatedir."/".strtolower($subdom["type"]);
|
||||
if ($subdom["has_https_option"] && in_array($subdom["https"],$this->httpsmodes)) {
|
||||
$template.="-".$subdom["https"];
|
||||
}
|
||||
$template.=".conf";
|
||||
if (!is_file($template)) {
|
||||
$msg->raise("ERROR","apache","Template $template not found for subdom ".$subdom["id"]." for domain ".$subdom["sub"].".".$subdom["domaine"].". Skipped");
|
||||
return 1;
|
||||
}
|
||||
|
||||
$subdom["fqdn"]=$subdom["sub"].(($subdom["sub"])?".":"").$subdom["domaine"];
|
||||
// SSL information $subdom["certificate_id"] may be ZERO => it means "take id 0 which is snakeoil cert"
|
||||
$cert = $ssl->get_certificate_path($subdom["certificate_id"]);
|
||||
if ($cert["chain"]) {
|
||||
$chainline="SSLCertificateChainFile ".$cert["chain"];
|
||||
} else {
|
||||
$chainline="";
|
||||
}
|
||||
// Replace needed vars in template file
|
||||
$tpl=file_get_contents($template);
|
||||
$tpl = strtr($tpl, array(
|
||||
"%%LOGIN%%" => $subdom['login'],
|
||||
"%%fqdn%%" => $subdom['fqdn'],
|
||||
"%%document_root%%" => getuserpath($subdom['login']) . $subdom['valeur'],
|
||||
"%%account_root%%" => getuserpath($subdom['login']),
|
||||
"%%redirect%%" => $subdom['valeur'],
|
||||
"%%UID%%" => $subdom['compte'],
|
||||
"%%GID%%" => $subdom['compte'],
|
||||
"%%mail_account%%" => $subdom['login']."@".$L_FQDN,
|
||||
"%%user%%" => "FIXME",
|
||||
"%%CRT%%" => $cert["cert"],
|
||||
"%%KEY%%" => $cert["key"],
|
||||
"%%CHAINLINE%%" => $chainline,
|
||||
));
|
||||
// and write the template
|
||||
$confdir = $this->vhostroot."/".substr($subdom["compte"],-1)."/".$subdom["compte"];
|
||||
@mkdir($confdir,0755,true);
|
||||
file_put_contents($confdir."/".$subdom["fqdn"].".conf",$tpl);
|
||||
$this->shouldreload=true;
|
||||
|
||||
return 0; // shell meaning => OK ;)
|
||||
} // hook_updatedomains_web_add
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* launched for each FQDN for which we want to delete a vhost template
|
||||
*/
|
||||
function hook_updatedomains_web_del($subdomid) {
|
||||
global $db;
|
||||
$db->query("SELECT sd.*, dt.only_dns, dt.has_https_option, m.login FROM domaines_type dt, sub_domaines sd LEFT JOIN membres m ON m.uid=sd.compte WHERE dt.name=sd.type AND sd.web_action!='OK' AND id=?;",array($subdomid));
|
||||
$db->next_record();
|
||||
$subdom=$db->Record;
|
||||
$confdir = $this->vhostroot."/".substr($subdom["compte"],-1)."/".$subdom["compte"];
|
||||
@unlink($confdir."/".$subdom["fqdn"].".conf");
|
||||
$this->shouldreload=true;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* launched at the very end of updatedomains
|
||||
*/
|
||||
function hook_updatedomains_web_post() {
|
||||
global $msg;
|
||||
if ($this->shouldreload) {
|
||||
|
||||
// concatenate all files into one
|
||||
$this->concat();
|
||||
|
||||
// reload apache
|
||||
$ret=0;
|
||||
exec("apache2ctl graceful 2>&1",$out,$ret);
|
||||
touch($this->reloadfile);
|
||||
if ($ret!=0) {
|
||||
$msg->raise("ERROR","apache","Error while reloading apache, error code is $ret\n".implode("\n",$out));
|
||||
} else {
|
||||
$msg->raise("INFO","apache","Apache reloaded");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Concatenate all files under $this->vhostroot
|
||||
* into one (mindepth=2 though),
|
||||
* this function is faster than any shell stuff :D
|
||||
*/
|
||||
private function concat() {
|
||||
global $msg;
|
||||
$d=opendir($this->vhostroot);
|
||||
$f=fopen($this->vhostroot."/vhosts_all.conf.new","wb");
|
||||
if (!$f) {
|
||||
$msg->raise("FATAL","apache","Can't write vhosts_all file");
|
||||
return false;
|
||||
}
|
||||
while (($c=readdir($d))!==false) {
|
||||
if (substr($c,0,1)!="." && is_dir($this->vhostroot."/".$c)) {
|
||||
$this->subconcat($f,$this->vhostroot."/".$c);
|
||||
}
|
||||
}
|
||||
closedir($d);
|
||||
fclose($f);
|
||||
rename($this->vhostroot."/vhosts_all.conf.new", $this->vhostroot."/vhosts_all.conf");
|
||||
}
|
||||
|
||||
private function subconcat($f,$root) {
|
||||
// recursive cat :)
|
||||
$d=opendir($root);
|
||||
while (($c=readdir($d))!==false) {
|
||||
if (substr($c,0,1)!=".") {
|
||||
if (is_dir($root."/".$c)) {
|
||||
$this->subconcat($f,$root."/".$c); // RECURSIVE CALL
|
||||
}
|
||||
if (is_file($root."/".$c)) {
|
||||
fputs($f,file_get_contents($root."/".$c)."\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($d);
|
||||
}
|
||||
|
||||
} // m_apache
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
----------------------------------------------------------------------
|
||||
LICENSE
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License (GPL)
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
To read the license please visit http://www.gnu.org/copyleft/gpl.html
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages BIND 9+ zone management templates in AlternC 3.5+
|
||||
*
|
||||
* @copyright AlternC-Team 2000-2018 https://alternc.com/
|
||||
*/
|
||||
class m_bind {
|
||||
|
||||
var $shouldreload;
|
||||
var $shouldreconfig;
|
||||
|
||||
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 $zone_file_directory = '/var/lib/alternc/bind/zones';
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/** Hook launched before any action by updatedomains
|
||||
* initialize the reload/reconfig flags used by POST
|
||||
* @NOTE launched as ROOT
|
||||
*/
|
||||
function hook_updatedomains_dns_pre() {
|
||||
$this->shouldreload=false;
|
||||
$this->shouldreconfig=false;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Hook launched for each ZONE for which we want a zone update (or create)
|
||||
* update the zone, create it if necessary,
|
||||
* and ask for reload or reconfig of bind9 depending on what happened
|
||||
* @NOTE launched as ROOT
|
||||
*/
|
||||
function hook_updatedomains_dns_add($dominfo) {
|
||||
global $L_FQDN,$L_NS1_HOSTNAME,$L_NS2_HOSTNAME,$L_DEFAULT_MX,$L_DEFAULT_SECONDARY_MX,$L_PUBLIC_IP,$L_PUBLIC_IPV6;
|
||||
|
||||
$domain = $dominfo["domaine"];
|
||||
$ttl = $dominfo["zonettl"];
|
||||
|
||||
// does it already exist?
|
||||
if (file_exists($this->zone_file_directory."/".$domain)) {
|
||||
list($islocked,$serial,$more)=$this->read_zone($domain);
|
||||
$serial++; // only increment serial for new zones
|
||||
} else {
|
||||
$more="";
|
||||
$serial=date("Ymd")."00";
|
||||
$islocked=false;
|
||||
}
|
||||
if ($islocked) return;
|
||||
|
||||
// Prepare a new zonefile from a template
|
||||
$zone = file_get_contents($this->ZONE_TEMPLATE);
|
||||
|
||||
// add the SUBDOMAIN entries
|
||||
$zone .= $this->conf_from_db($domain);
|
||||
|
||||
// substitute ALTERNC & domain variables
|
||||
$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@@" => $serial,
|
||||
"@@PUBLIC_IP@@" => "$L_PUBLIC_IP",
|
||||
"@@PUBLIC_IPV6@@" => "$L_PUBLIC_IPV6",
|
||||
"@@ZONETTL@@" => $ttl,
|
||||
));
|
||||
|
||||
// add the "END ALTERNC CONF line";
|
||||
$zone .= ";;; END ALTERNC AUTOGENERATE CONFIGURATION\n";
|
||||
|
||||
// add the manually entered info:
|
||||
$zone .= $more;
|
||||
file_put_contents($this->zone_file_directory."/".$domain,$zone);
|
||||
|
||||
// add the line into bind9 conf:
|
||||
if (add_line_to_file(
|
||||
$this->NAMED_CONF,
|
||||
trim(strtr(
|
||||
file_get_contents($this->NAMED_TEMPLATE),
|
||||
array(
|
||||
"@@DOMAIN@@" => $domain,
|
||||
"@@ZONE_FILE@@" => $this->zone_file_directory."/".$domain
|
||||
)
|
||||
)))
|
||||
) {
|
||||
$this->shouldreconfig=true;
|
||||
} else {
|
||||
$this->shouldreload=true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Hook launched for each ZONE for which we want a zone DELETE
|
||||
* remove the zone and its file,
|
||||
* and if any action happened, ask for bind RECONFIG at posttime
|
||||
* @NOTE launched as ROOT
|
||||
*/
|
||||
function hook_updatedomains_dns_del($dominfo) {
|
||||
$domain = $dominfo["domaine"];
|
||||
if (del_line_from_file(
|
||||
$this->NAMED_CONF,
|
||||
trim(strtr(
|
||||
file_get_contents($this->NAMED_TEMPLATE),
|
||||
array(
|
||||
"@@DOMAIN@@" => $domain,
|
||||
"@@ZONE_FILE@@" => $this->zone_file_directory."/".$domain
|
||||
)
|
||||
)))
|
||||
) {
|
||||
$this->shouldreconfig=true;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@unlink($this->zone_file_directory."/".$domain);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Hook function launched at the very end of updatedomains
|
||||
* here, we just reload OR reconfig (or both) bind9 depending
|
||||
* on what happened before.
|
||||
* @NOTE launched as ROOT
|
||||
*/
|
||||
function hook_updatedomains_dns_post() {
|
||||
global $msg;
|
||||
if ($this->shouldreload) {
|
||||
$ret=0;
|
||||
exec($this->RNDC." reload 2>&1",$out,$ret);
|
||||
if ($ret!=0) {
|
||||
$msg->raise("ERROR","bind","Error while reloading bind, error code is $ret\n".implode("\n",$out));
|
||||
} else {
|
||||
$msg->raise("INFO","bind","Bind reloaded");
|
||||
}
|
||||
}
|
||||
if ($this->shouldreconfig) {
|
||||
$ret=0;
|
||||
exec($this->RNDC." reconfig 2>&1",$out,$ret);
|
||||
if ($ret!=0) {
|
||||
$msg->raise("ERROR","bind","Error while reconfiguring bind, error code is $ret\n".implode("\n",$out));
|
||||
} else {
|
||||
$msg->raise("INFO","bind","Bind reconfigured");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* read a zone file for $domain,
|
||||
* @param $domain string the domain name
|
||||
* @return array with 3 informations:
|
||||
* is the domain locked? (boolean), what's the current serial (integer), the data after alternc conf (string of lines)
|
||||
*/
|
||||
function read_zone($domain) {
|
||||
$f=fopen($this->zone_file_directory."/".$domain,"rb");
|
||||
$islocked=false;
|
||||
$more="";
|
||||
$serial=date("Ymd")."00";
|
||||
while ($s=fgets($f,4096)) {
|
||||
if (preg_match("#\;\s*LOCKED:YES#i",$s)) {
|
||||
$islocked=true;
|
||||
}
|
||||
if (preg_match("/\s*(\d{10})\s+\;\sserial\s?/", $s,$mat)) {
|
||||
$serial=$mat[1];
|
||||
}
|
||||
if (preg_match('/\;\s*END\sALTERNC\sAUTOGENERATE\sCONFIGURATION(.*)/s', $s)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ($s=fgets($f,4096)) {
|
||||
$more.=$s;
|
||||
}
|
||||
return array($islocked,$serial,$more);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Return the part of the conf we got from the sub_domaines table
|
||||
* @global m_mysql $db
|
||||
* @param string $domain
|
||||
* @return string a zonefile excerpt
|
||||
*/
|
||||
function conf_from_db($domain) {
|
||||
global $db;
|
||||
$db->query("
|
||||
SELECT
|
||||
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="";
|
||||
while ($db->next_record()) {
|
||||
$t.= $db->f('ENTRY')."\n";
|
||||
}
|
||||
return $t;
|
||||
}
|
||||
|
||||
|
||||
} // m_bind
|
||||
|
|
@ -54,15 +54,7 @@ class m_dom {
|
|||
* du domaine par update_domains.sh
|
||||
* @access private
|
||||
*/
|
||||
var $fic_lock_cron = "/run/alternc/cron.lock";
|
||||
|
||||
/**
|
||||
* Le cron a-t-il été bloqué ?
|
||||
* Il faut appeler les fonctions privées lock et unlock entre les
|
||||
* appels aux domaines.
|
||||
* @access private
|
||||
*/
|
||||
var $islocked = false;
|
||||
const fic_lock_cron = "/run/alternc/cron.lock";
|
||||
|
||||
var $type_local = "VHOST";
|
||||
var $type_url = "URL";
|
||||
|
@ -84,9 +76,10 @@ class m_dom {
|
|||
* Constructeur
|
||||
*/
|
||||
function m_dom() {
|
||||
global $L_FQDN;
|
||||
global $L_FQDN, $domislocked;
|
||||
$this->tld_no_check_at_all = variable_get('tld_no_check_at_all', 0, 'Disable ALL check on the TLD (users will be able to add any domain)', array('desc' => 'Disabled', 'type' => 'boolean'));
|
||||
variable_get('mailname_bounce', $L_FQDN, 'FQDN of the mail server, used to create vhost virtual mail_adress.', array('desc' => 'FQDN', 'type' => 'string'));
|
||||
$domislocked=false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -642,35 +635,35 @@ class m_dom {
|
|||
* @param string $dom nom de domaine é effacer
|
||||
* @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon.
|
||||
*/
|
||||
function del_domain($dom) {
|
||||
function del_domain($domain) {
|
||||
global $db, $msg, $hooks;
|
||||
$msg->log("dom", "del_domain", $dom);
|
||||
$dom = strtolower($dom);
|
||||
$msg->log("dom", "del_domain", $domain);
|
||||
$domain = strtolower($domain);
|
||||
|
||||
$this->lock();
|
||||
if (!$r = $this->get_domain_all($dom)) {
|
||||
if (!$r = $this->get_domain_all($domain)) {
|
||||
return false;
|
||||
}
|
||||
$this->unlock();
|
||||
|
||||
// Call Hooks to delete the domain and the MX management:
|
||||
// TODO : the 2 calls below are using an OLD hook call, FIXME: remove them when unused
|
||||
$hooks->invoke("alternc_del_domain", array($dom));
|
||||
$hooks->invoke("alternc_del_mx_domain", array($dom));
|
||||
$hooks->invoke("alternc_del_domain", array($domain));
|
||||
$hooks->invoke("alternc_del_mx_domain", array($domain));
|
||||
// New hook calls:
|
||||
$hooks->invoke("hook_dom_del_domain", array($r["id"]));
|
||||
$hooks->invoke("hook_dom_del_mx_domain", array($r["id"]));
|
||||
|
||||
// Now mark the domain for deletion:
|
||||
$db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ?;", array($dom));
|
||||
$this->set_dns_action($dom, 'DELETE');
|
||||
$db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ?;", array($domain));
|
||||
$this->set_dns_action($domain, 'DELETE');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
function domshort($dom, $sub = "") {
|
||||
return str_replace("-", "", str_replace(".", "", empty($sub) ? "" : "$sub.") . $dom);
|
||||
function domshort($domain, $sub = "") {
|
||||
return str_replace("-", "", str_replace(".", "", empty($sub) ? "" : "$sub.") . $domain);
|
||||
}
|
||||
|
||||
|
||||
|
@ -694,11 +687,11 @@ class m_dom {
|
|||
* @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon.
|
||||
*/
|
||||
function add_domain($domain, $dns, $noerase = false, $force = false, $isslave = false, $slavedom = "") {
|
||||
global $db, $msg, $quota, $L_FQDN, $tld, $cuid, $hooks;
|
||||
global $db, $msg, $quota, $L_FQDN, $tld, $cuid, $hooks, $domislocked;
|
||||
$msg->log("dom", "add_domain", $domain);
|
||||
|
||||
// Locked ?
|
||||
if (!$this->islocked) {
|
||||
if (!$domislocked) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- No lock on the domains!"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1037,10 +1030,10 @@ class m_dom {
|
|||
*
|
||||
*/
|
||||
function get_domain_all($dom) {
|
||||
global $db, $msg, $cuid;
|
||||
global $db, $msg, $cuid, $domislocked;
|
||||
$msg->debug("dom", "get_domain_all", $dom);
|
||||
// Locked ?
|
||||
if (!$this->islocked) {
|
||||
if (!$domislocked) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- No lock on the domains!"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1072,13 +1065,14 @@ class m_dom {
|
|||
$db->query("SELECT sd.*, dt.description AS type_desc, dt.only_dns, dt.advanced, dt.has_https_option FROM sub_domaines sd LEFT JOIN domaines_type dt on UPPER(dt.name)=UPPER(sd.type) WHERE compte= ? AND domaine= ? ORDER BY dt.advanced,sd.sub,sd.type ;", array($cuid, $dom));
|
||||
// Pas de webmail, on le cochera si on le trouve.
|
||||
$r["sub"] = array();
|
||||
$data = $db->fetchAll();
|
||||
foreach($data as $i=>$record) {
|
||||
$i=0;
|
||||
while ($record=$db->fetch()) {
|
||||
$r["sub"][$i] = $record;
|
||||
// FIXME : replace sub by name and dest by valeur in the code that exploits this function :
|
||||
$r["sub"][$i]["name"] = $record["sub"];
|
||||
$r["sub"][$i]["dest"] = $record["valeur"];
|
||||
$r["sub"][$i]["fqdn"] = ((!empty($r["sub"][$i]["name"])) ? $r["sub"][$i]["name"] . "." : "") . $r["name"];
|
||||
$i++;
|
||||
}
|
||||
$db->free();
|
||||
return $r;
|
||||
|
@ -1098,10 +1092,10 @@ class m_dom {
|
|||
* Retourne FALSE si une erreur s'est produite.
|
||||
*/
|
||||
function get_sub_domain_all($sub_domain_id) {
|
||||
global $db, $msg, $cuid;
|
||||
global $db, $msg, $cuid, $domislocked;
|
||||
$msg->debug("dom", "get_sub_domain_all", $sub_domain_id);
|
||||
// Locked ?
|
||||
if (!$this->islocked) {
|
||||
if (!$domislocked) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- No lock on the domains!"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1263,10 +1257,10 @@ class m_dom {
|
|||
* @return boolean true if the preference has been set
|
||||
*/
|
||||
function set_subdomain_ssl_provider($sub_domain_id,$provider) {
|
||||
global $db, $msg, $cuid, $ssl;
|
||||
global $db, $msg, $cuid, $ssl, $domislocked;
|
||||
$msg->log("dom", "set_sub_domain_ssl_provider", $sub_domain_id." / ".$provider);
|
||||
// Locked ?
|
||||
if (!$this->islocked) {
|
||||
if (!$domislocked) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- No lock on the domains!"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1308,13 +1302,14 @@ class m_dom {
|
|||
* de $type (url, ip, dossier...)
|
||||
* @param string $https the HTTPS behavior : HTTP(redirect https to http),
|
||||
* HTTPS(redirect http to https) or BOTH (both hosted at the same place)
|
||||
* or nothing "" when not applicable for this domain type.
|
||||
* @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon.
|
||||
*/
|
||||
function set_sub_domain($dom, $sub, $type, $dest, $sub_domain_id = 0, $https) {
|
||||
global $db, $msg, $cuid, $bro;
|
||||
function set_sub_domain($dom, $sub, $type, $dest, $sub_domain_id = 0, $https="") {
|
||||
global $db, $msg, $cuid, $bro, $domislocked;
|
||||
$msg->log("dom", "set_sub_domain", $dom . "/" . $sub . "/" . $type . "/" . $dest);
|
||||
// Locked ?
|
||||
if (!$this->islocked) {
|
||||
if (!$domislocked) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- No lock on the domains!"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1396,10 +1391,10 @@ class m_dom {
|
|||
*
|
||||
*/
|
||||
function del_sub_domain($sub_domain_id) {
|
||||
global $db, $msg;
|
||||
global $db, $msg, $domislocked;
|
||||
$msg->log("dom", "del_sub_domain", $sub_domain_id);
|
||||
// Locked ?
|
||||
if (!$this->islocked) {
|
||||
if (!$domislocked) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- No lock on the domains!"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1442,11 +1437,11 @@ class m_dom {
|
|||
* TRUE sinon.
|
||||
*
|
||||
*/
|
||||
function edit_domain($dom, $dns, $gesmx, $force = false, $ttl = 86400) {
|
||||
global $db, $msg, $hooks;
|
||||
function edit_domain($dom, $dns, $gesmx, $force = false, $ttl = 3600) {
|
||||
global $db, $msg, $hooksthis;
|
||||
$msg->log("dom", "edit_domain", $dom . "/" . $dns . "/" . $gesmx);
|
||||
// Locked ?
|
||||
if (!$this->islocked && !$force) {
|
||||
if (!$domislocked && !$force) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- No lock on the domains!"));
|
||||
return false;
|
||||
}
|
||||
|
@ -1765,15 +1760,20 @@ class m_dom {
|
|||
* @access private
|
||||
*/
|
||||
function lock() {
|
||||
global $msg;
|
||||
global $msg,$domislocked;
|
||||
$msg->debug("dom", "lock");
|
||||
if ($this->islocked) {
|
||||
if ($domislocked) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- Lock already obtained!"));
|
||||
}
|
||||
while (file_exists($this->fic_lock_cron)) {
|
||||
// wait for the file to disappear, or at most 15min:
|
||||
while (file_exists(m_dom::fic_lock_cron) && filemtime(m_dom::fic_lock_cron)>(time()-900)) {
|
||||
clearstatcache();
|
||||
sleep(2);
|
||||
}
|
||||
$this->islocked = true;
|
||||
@touch(m_dom::fic_lock_cron);
|
||||
$domislocked = true;
|
||||
// extra safe :
|
||||
register_shutdown_function(array("m_dom","unlock"),1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1783,13 +1783,15 @@ class m_dom {
|
|||
* return true
|
||||
* @access private
|
||||
*/
|
||||
function unlock() {
|
||||
global $msg;
|
||||
function unlock($isshutdown=0) {
|
||||
global $msg,$domislocked;
|
||||
$msg->debug("dom", "unlock");
|
||||
if (!$this->islocked) {
|
||||
if (!$isshutdown && !$domislocked) {
|
||||
$msg->raise("ERROR", "dom", _("--- Program error --- No lock on the domains!"));
|
||||
}
|
||||
$this->islocked = false;
|
||||
// don't use $this since we may be called by register_shutdown_function out of an object instance.
|
||||
@unlink(m_dom::fic_lock_cron);
|
||||
$domislocked = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1892,199 +1894,103 @@ class m_dom {
|
|||
|
||||
|
||||
/**
|
||||
* Return an array with all the needed parameters to generate conf
|
||||
* of a vhost.
|
||||
* If no parameters, return the parameters for ALL the vhost.
|
||||
* Optionnal parameters: id of the sub_domaines
|
||||
* */
|
||||
function generation_parameters($id = null, $only_apache = true) {
|
||||
global $db, $msg;
|
||||
$msg->log("dom", "generation_parameters");
|
||||
$params = "";
|
||||
/** 2016_05_18 : this comments was here before escaping the request... is there still something to do here ?
|
||||
* // BUG BUG BUG FIXME
|
||||
* // Suppression de comptes -> membres existe pas -> domaines a supprimer ne sont pas lister
|
||||
*/
|
||||
$query = "
|
||||
select
|
||||
sd.id as sub_id,
|
||||
lower(sd.type) as type,
|
||||
m.login,
|
||||
m.uid as uid,
|
||||
if(length(sd.sub)>0,concat_ws('.',sd.sub,sd.domaine),sd.domaine) as fqdn,
|
||||
concat_ws('@',m.login,v.value) as mail,
|
||||
sd.valeur
|
||||
from
|
||||
sub_domaines sd left join membres m on sd.compte=m.uid,
|
||||
variable v,
|
||||
domaines_type dt
|
||||
where
|
||||
v.name='mailname_bounce'
|
||||
and lower(dt.name) = lower(sd.type)";
|
||||
$query_args = array();
|
||||
|
||||
if (!is_null($id) && intval($id) == $id) {
|
||||
$query .= " AND sd.id = ? ";
|
||||
array_push($query_args, intval($id));
|
||||
}
|
||||
if ($only_apache) {
|
||||
$query .=" and dt.only_dns is false ";
|
||||
* complex process to manage domain and subdomain updates
|
||||
* Launched every minute by a cron as root
|
||||
* should launch hooks for each domain or subdomain,
|
||||
* so that apache & bind could do their job
|
||||
*/
|
||||
function update_domains() {
|
||||
global $db, $hooks;
|
||||
if (posix_getuid()!=0) {
|
||||
echo "FATAL: please lauch me as root\n";
|
||||
exit();
|
||||
}
|
||||
|
||||
$query .= "
|
||||
order by
|
||||
m.login,
|
||||
sd.domaine,
|
||||
sd.sub;";
|
||||
$this->lock();
|
||||
|
||||
// fix in case we forgot to delete SUBDOMAINS before deleting a DOMAIN
|
||||
$db->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';");
|
||||
|
||||
$db->query($query, $query_args);
|
||||
|
||||
$r = array();
|
||||
// Search for things to do on DOMAINS:
|
||||
$db->query("SELECT * FROM domaines WHERE dns_action!='OK';");
|
||||
$alldoms=array();
|
||||
while ($db->next_record()) {
|
||||
$r[$db->Record['sub_id']] = $db->Record;
|
||||
$alldoms[$db->Record["id"]]=$db->Record;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
// now launch hooks
|
||||
if (count($alldoms)) {
|
||||
$hooks->invoke("hook_updatedomains_dns_pre");
|
||||
foreach($alldoms as $id=>$onedom) {
|
||||
if ($onedom["gesdns"]==0 || $onedom["dns_action"]=="DELETE") {
|
||||
$ret = $hooks->invoke("hook_updatedomains_dns_del",array($onedom));
|
||||
} else {
|
||||
$ret = $hooks->invoke("hook_updatedomains_dns_add",array($onedom));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an array with all informations of the domains_type
|
||||
* used to generate Apache conf.
|
||||
* Die if templates missing.
|
||||
* Warning: an Apache domains_type must have 'only_dns' == TRUE
|
||||
*
|
||||
* */
|
||||
function generation_domains_type() {
|
||||
global $dom;
|
||||
$d = array();
|
||||
foreach ($dom->domains_type_lst() as $k => $v) {
|
||||
if ($v['only_dns'] == true) {
|
||||
continue;
|
||||
if ($onedom["dns_action"]=="DELETE") {
|
||||
$db->query("DELETE FROM domaines WHERE domaine=?;",array($onedom));
|
||||
} else {
|
||||
// we keep the highest result returned by hooks...
|
||||
rsort($ret,SORT_NUMERIC); $returncode=$ret[0];
|
||||
$db->query("UPDATE domaines SET dns_result=?, dns_action='OK' WHERE domaine=?;",array($returncode,$onedom["domaine"]));
|
||||
}
|
||||
}
|
||||
if (!$j = file_get_contents(ALTERNC_APACHE2_GEN_TMPL_DIR . '/' . strtolower($k) . '.conf')) {
|
||||
die("Error: missing file for $k");
|
||||
}
|
||||
$d[$k] = $v;
|
||||
$d[$k]['tpl'] = $j;
|
||||
}
|
||||
return $d;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Launch old fashionned hooks as there was in AlternC 1.0
|
||||
* @TODO: do we still need that?
|
||||
*/
|
||||
function generate_conf_oldhook($action, $lst_sub, $sub_obj = null) {
|
||||
if (is_null($sub_obj)) {
|
||||
$sub_obj = $this->generation_parameters(null, false);
|
||||
}
|
||||
if (!isset($lst_sub[strtoupper($action)]) || empty($lst_sub[strtoupper($action)])) {
|
||||
return false;
|
||||
$hooks->invoke("hook_updatedomains_dns_post");
|
||||
}
|
||||
|
||||
$lst_by_type = $lst_sub[strtoupper($action)];
|
||||
|
||||
foreach ($lst_by_type as $type => $lid_arr) {
|
||||
$script = "/etc/alternc/functions_hosting/hosting_" . strtolower($type) . ".sh";
|
||||
if (!@is_executable($script)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($lid_arr as $lid) {
|
||||
$o = $sub_obj[$lid];
|
||||
$cmd = $script . " " . escapeshellcmd(strtolower($action)) . " ";
|
||||
$cmd .= escapeshellcmd($o['fqdn']) . " " . escapeshellcmd($o['valeur']);
|
||||
|
||||
system($cmd);
|
||||
}
|
||||
} // foreach $lst_by_type
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate apache configuration.
|
||||
* Die if a specific FQDN have 2 vhost conf.
|
||||
*
|
||||
* */
|
||||
function generate_apacheconf($p = null) {
|
||||
// Get the parameters
|
||||
$lst = $this->generation_parameters($p);
|
||||
|
||||
$gdt = $this->generation_domains_type();
|
||||
|
||||
// Initialize duplicate check
|
||||
$check_dup = array();
|
||||
|
||||
$ret = '';
|
||||
foreach ($lst as $p) {
|
||||
// Check if duplicate
|
||||
if (in_array($p['fqdn'], $check_dup)) {
|
||||
die("Error: duplicate fqdn : " . $p['fqdn']);
|
||||
// Search for things to do on SUB-DOMAINS:
|
||||
$db->query("SELECT sd.*, dt.only_dns FROM domaines_type dt, sub_domaines sd WHERE dt.name=sd.type AND sd.web_action!='OK';");
|
||||
$alldoms=array();
|
||||
$ignore=array();
|
||||
$delete=array();
|
||||
while ($db->next_record()) {
|
||||
// only_dns=1 => weird, we should not have web_action SET to something else than OK ... anyway, skip it
|
||||
if ($db->Record["only_dns"]) {
|
||||
if ($db->Record["web_action"]=="DELETE") {
|
||||
$delete[]=$db->Record["id"];
|
||||
} else {
|
||||
$ignore[]=$db->Record["id"];
|
||||
}
|
||||
} else {
|
||||
$check_dup[] = $p['fqdn'];
|
||||
$alldoms[$db->Record["id"]]=$db->Record;
|
||||
}
|
||||
}
|
||||
foreach($delete as $id) {
|
||||
$db->query("DELETE FROM sub_domaines WHERE id=?;",array($id));
|
||||
}
|
||||
foreach($ignore as $id) {
|
||||
// @FIXME (unsure it's useful) maybe we could check that no file exist for this subdomain ?
|
||||
$db->query("UPDATE sub_domaines SET web_action='OK' WHERE id=?;",array($id));
|
||||
}
|
||||
// now launch hooks
|
||||
if (count($alldoms)) {
|
||||
$hooks->invoke("hook_updatedomains_web_pre");
|
||||
foreach($alldoms as $id=>$subdom) {
|
||||
// is it a delete (DISABLED or DELETE)
|
||||
if ($subdom["web_action"]=="DELETE" || strtoupper(substr($subdom["enable"],0,7))=="DISABLE") {
|
||||
$ret = $hooks->invoke("hook_updatedomains_web_del",array($subdom["id"]));
|
||||
} else {
|
||||
$hooks->invoke("hook_updatedomains_web_before",array($subdom["id"])); // give a chance to get SSL cert before ;)
|
||||
$ret = $hooks->invoke("hook_updatedomains_web_add",array($subdom["id"]));
|
||||
$hooks->invoke("hook_updatedomains_web_after",array($subdom["id"]));
|
||||
}
|
||||
|
||||
// Get the needed template
|
||||
$tpl = $gdt[$p['type']] ['tpl'];
|
||||
|
||||
// Replace needed vars
|
||||
$tpl = strtr($tpl, array(
|
||||
"%%LOGIN%%" => $p['login'],
|
||||
"%%fqdn%%" => $p['fqdn'],
|
||||
"%%document_root%%" => getuserpath($p['login']) . $p['valeur'],
|
||||
"%%account_root%%" => getuserpath($p['login']),
|
||||
"%%redirect%%" => $p['valeur'],
|
||||
"%%UID%%" => $p['uid'],
|
||||
"%%GID%%" => $p['uid'],
|
||||
"%%mail_account%%" => $p['mail'],
|
||||
"%%user%%" => "FIXME",
|
||||
));
|
||||
|
||||
// Security check
|
||||
if ($p['uid'] < 1999) { // if UID is not an AlternC uid
|
||||
$ret.= "# ERROR: Sub_id: " . $p['sub_id'] . "- The uid seem to be dangerous\n";
|
||||
continue;
|
||||
if ($subdom["web_action"]=="DELETE") {
|
||||
$db->query("DELETE FROM sub_domaines WHERE id=?;",array($id));
|
||||
} else {
|
||||
// we keep the highest result returned by hooks...
|
||||
rsort($ret,SORT_NUMERIC); $returncode=$ret[0];
|
||||
$db->query("UPDATE sub_domaines SET web_result=?, web_action='OK' WHERE id=?;",array($returncode,$id));
|
||||
}
|
||||
}
|
||||
|
||||
// Return the conf
|
||||
$ret.= "# Sub_id: " . $p['sub_id'] . "\n" . $tpl;
|
||||
$hooks->invoke("hook_updatedomains_web_post");
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
||||
$this->unlock();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an array with the list of id of sub_domains waiting for an action
|
||||
*/
|
||||
function generation_todo() {
|
||||
global $db, $msg;
|
||||
$msg->debug("dom", "generation_todo");
|
||||
$db->query("select id as sub_id, web_action, type from sub_domaines where web_action !='ok';");
|
||||
$r = array();
|
||||
while ($db->next_record()) {
|
||||
$r[strtoupper($db->Record['web_action'])][strtoupper($db->Record['type'])][] = $db->f('sub_id');
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
|
||||
function subdomain_modif_are_done($sub_domain_id, $action) {
|
||||
global $db;
|
||||
$sub_domain_id = intval($sub_domain_id);
|
||||
switch (strtolower($action)) {
|
||||
case "delete":
|
||||
$sql = "DELETE FROM sub_domaines WHERE id =$sub_domain_id;";
|
||||
break;
|
||||
default:
|
||||
$sql = "UPDATE sub_domaines SET web_action='OK' WHERE id='$sub_domain_id'; ";
|
||||
}
|
||||
$db->query($sql);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $dns_action
|
||||
*/
|
||||
|
@ -2095,15 +2001,8 @@ class m_dom {
|
|||
}
|
||||
|
||||
|
||||
function set_dns_result($domain, $dns_result) {
|
||||
global $db;
|
||||
$db->query("UPDATE domaines SET dns_result= ? WHERE domaine= ?; ", array($dns_result, $domain));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List if there is problems in the domains.
|
||||
* List if there are problems on the domain.
|
||||
* Problems can appear when editing domains type properties
|
||||
*/
|
||||
function get_problems($domain) {
|
||||
|
@ -2160,6 +2059,8 @@ class m_dom {
|
|||
_("Default mail server");
|
||||
_("Default backup mail server");
|
||||
_("AlternC panel access");
|
||||
_("DKIM Key");
|
||||
_("Email autoconfiguration");
|
||||
}
|
||||
|
||||
} /* Class m_domains */
|
||||
|
|
|
@ -99,8 +99,8 @@ class m_lxc implements vm {
|
|||
}
|
||||
}
|
||||
|
||||
$msg = serialize($params);
|
||||
if (fwrite($fp, $msg . "\n") < 0) {
|
||||
$message = serialize($params);
|
||||
if (fwrite($fp, $message . "\n") < 0) {
|
||||
$this->error[] = 'Unable to send data';
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -135,22 +135,22 @@ class m_lxc implements vm {
|
|||
$pass = $pass ? $pass : $mem->user['pass'];
|
||||
$uid = $uid ? $uid : $mem->user['uid'];
|
||||
|
||||
$msgg = array('action' => 'start', 'login' => $login, 'pass' => $pass, 'uid' => $uid);
|
||||
$msgg['mysql_host'] = $mysql->dbus->Host;
|
||||
$message = array('action' => 'start', 'login' => $login, 'pass' => $pass, 'uid' => $uid);
|
||||
$message['mysql_host'] = $mysql->dbus->Host;
|
||||
|
||||
$res = $this->sendMessage($msgg);
|
||||
$res = $this->sendMessage($message);
|
||||
if ($res === FALSE) {
|
||||
return $this->error;
|
||||
} else {
|
||||
$data = unserialize($res);
|
||||
$error = (int) $data['error'];
|
||||
$hostname = $data['hostname'];
|
||||
$msg = $data['msg'];
|
||||
$message = $data['msg'];
|
||||
$date_start = 'NOW()';
|
||||
$uid = $mem->user['uid'];
|
||||
|
||||
if ($error != 0) {
|
||||
$msg->raise("ERROR", 'lxc', _($msg));
|
||||
$msg->raise("ERROR", 'lxc', _($message));
|
||||
return FALSE;
|
||||
}
|
||||
$db->query("INSERT INTO vm_history (ip,date_start,uid,serialized_object) VALUES (?, ?, ?, ?);", array($hostname, $date_start, $uid, $res));
|
||||
|
@ -166,8 +166,8 @@ class m_lxc implements vm {
|
|||
global $mem;
|
||||
|
||||
$login = $login ? $login : $mem->user['login'];
|
||||
$msgg = array('action' => 'get', 'login' => $login);
|
||||
$res = $this->sendMessage($msgg);
|
||||
$message = array('action' => 'get', 'login' => $login);
|
||||
$res = $this->sendMessage($message);
|
||||
if (!$res) {
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -469,9 +469,9 @@ ORDER BY
|
|||
if ($db->next_record()) {
|
||||
$db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ? AND type='txt' AND (sub='' AND valeur LIKE 'v=spf1 %') OR (sub='_dmarc' AND valeur LIKE 'v=dmarc1;%');", array($db->Record["domaine"]));
|
||||
$db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ? AND (type='defmx' OR type='defmx2');", array($db->Record["domaine"]));
|
||||
$db->query("UPDATE domaines SET dns_action='UPDATE' WHERE id= ? ;", array($dom_id));
|
||||
$db->query("UPDATE domaines SET dns_action='UPDATE' WHERE id= ? ;", array($dom_id));
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -912,6 +912,7 @@ ORDER BY
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* hook function called by AlternC when a domain is created for
|
||||
* the current user account using the SLAVE DOMAIN feature
|
||||
|
@ -928,6 +929,7 @@ ORDER BY
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* hook function called by AlternC when a domain is created for
|
||||
* the current user account
|
||||
|
@ -937,7 +939,7 @@ ORDER BY
|
|||
* @access private
|
||||
*/
|
||||
function hook_dom_add_mx_domain($domain_id) {
|
||||
global $msg, $mem, $db;
|
||||
global $msg, $mem, $db, $L_FQDN;
|
||||
$msg->log("mail", "hook_dom_add_mx_domain", $domain_id);
|
||||
|
||||
$db->query("SELECT value FROM variable where name='mailname_bounce';");
|
||||
|
@ -947,8 +949,9 @@ ORDER BY
|
|||
}
|
||||
$mailname = $db->f("value");
|
||||
// set spf & dmarc for this domain
|
||||
$db->query("SELECT domaine FROM domaines WHERE id= ?;", array($domain_id));
|
||||
$db->query("SELECT domaine,compte FROM domaines WHERE id= ?;", array($domain_id));
|
||||
if ($db->next_record()) {
|
||||
$this->set_dns_autoconf($db->Record["domaine"],$db->Record["compte"]);
|
||||
if ($spf = variable_get("default_spf_value")) {
|
||||
$this->set_dns_spf($db->Record["domaine"], $spf);
|
||||
}
|
||||
|
@ -960,13 +963,14 @@ ORDER BY
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* hook function called by variables when a variable is changed
|
||||
* @access private
|
||||
*/
|
||||
function hook_variable_set($name, $old, $new) {
|
||||
global $msg, $db;
|
||||
$msg->log("mail", "hook_variable_set($name,$old,$new)");
|
||||
$msg->log("mail", "hook_variable_set($name,$old,$new)");
|
||||
|
||||
if ($name == "default_spf_value") {
|
||||
$new = trim($new);
|
||||
|
@ -991,7 +995,34 @@ ORDER BY
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Add dns entries for autodiscover / autoconf on the domain
|
||||
*/
|
||||
function set_dns_autoconf($domain,$uid=-1) {
|
||||
global $db, $L_FQDN, $cuid;
|
||||
$changed=false;
|
||||
if ($uid==-1) $uid=$cuid;
|
||||
|
||||
$db->query("SELECT domaine,sub,type,valeur FROM sub_domaines WHERE domaine=? AND sub='autodiscover' AND type='autodiscover';",array($domain));
|
||||
if (!$db->next_record()) {
|
||||
$db->query("INSERT INTO sub_domaines SET domaine=?, compte=?, sub='autodiscover', type='autodiscover', valeur='';",array($domain,$uid));
|
||||
$changed=true;
|
||||
}
|
||||
$db->query("SELECT domaine,sub,type,valeur FROM sub_domaines WHERE domaine=? AND sub='autoconfig' AND type='autodiscover';",array($domain));
|
||||
if (!$db->next_record()) {
|
||||
$db->query("INSERT INTO sub_domaines SET domaine=?, compte=?, sub='autoconfig', type='autodiscover', valeur='';",array($domain,$uid));
|
||||
$changed=true;
|
||||
}
|
||||
if ($changed) {
|
||||
$db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine= ?;", array($domain));
|
||||
}
|
||||
return $changed;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Set or UPDATE the DNS record for the domain $dom(str) to be $spf
|
||||
* account's login is current and if not it's $login.
|
||||
|
@ -1022,6 +1053,7 @@ ORDER BY
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Set or UPDATE the DNS record for the domain $dom(str) to be $dmarc
|
||||
* account's login is current and if not it's $login.
|
||||
|
@ -1055,5 +1087,139 @@ ORDER BY
|
|||
}
|
||||
|
||||
|
||||
/** Manage DKIM when adding / removing a domain MX management */
|
||||
var $shouldreloaddkim;
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Hook launched before doing anything dns-related
|
||||
*/
|
||||
function hook_updatedomains_dns_pre() {
|
||||
global $db;
|
||||
// for each domain where we don't have the MX or the DNS, remove the DKIM setup
|
||||
$this->shouldreloaddkim=false;
|
||||
$db->query("SELECT domaine,compte,gesdns,gesmx FROM domaines WHERE dns_action!='OK';");
|
||||
$add=array();
|
||||
$del=array();
|
||||
while ($db->next_record()) {
|
||||
if ($db->Record["gesdns"]==0 || $db->Record["gesmx"]==0) {
|
||||
$del[]=$db->Record;
|
||||
} else {
|
||||
$add[]=$db->Record;
|
||||
}
|
||||
}
|
||||
foreach($add as $domain) {
|
||||
$this->dkim_add($domain["domaine"],$domain["compte"]);
|
||||
}
|
||||
foreach($del as $domain) {
|
||||
$this->dkim_del($domain["domaine"],$domain["compte"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Hook launched after doing anything dns-related
|
||||
*/
|
||||
function hook_updatedomains_dns_post() {
|
||||
if ($this->shouldreloaddkim) {
|
||||
exec("service opendkim reload");
|
||||
$this->shouldreloaddkim=false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Add a domain into OpenDKIM configuration
|
||||
*/
|
||||
function dkim_add($domain,$uid) {
|
||||
global $db;
|
||||
$target_dir = "/etc/opendkim/keys/$domain";
|
||||
|
||||
// Create a dkim key when it's not already there :
|
||||
if (!file_exists($target_dir.'/alternc.txt')) {
|
||||
$this->shouldreloaddkim=true;
|
||||
if (! is_dir($target_dir)) mkdir($target_dir); // create dir
|
||||
// Generate the key, 1200 bits (better than 1024)
|
||||
$old_dir=getcwd();
|
||||
chdir($target_dir);
|
||||
exec('opendkim-genkey -b 1200 -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');
|
||||
|
||||
add_line_to_file("/etc/opendkim/KeyTable","alternc._domainkey.".$domain." ".$domain.":alternc:/etc/opendkim/keys/".$domain."/alternc.private");
|
||||
add_line_to_file("/etc/opendkim/SigningTable",$domain." alternc._domainkey.".$domain);
|
||||
}
|
||||
|
||||
// Search for the subdomain entry, if it's not already there, create it:
|
||||
$db->query("SELECT id FROM sub_domaines WHERE domaine=? AND sub='alternc._domainkey';",array($domain));
|
||||
if (!$db->next_record()) {
|
||||
// Add subdomaine entry
|
||||
$dkim_key=$this->dkim_get_entry($domain);
|
||||
$db->query("INSERT INTO sub_domaines SET domaine=?, compte=?, sub='alternc._domainkey', type='dkim', valeur=?;",array($domain,$uid,$dkim_key));
|
||||
// no need to do DNS_ACTION="UPDATE" => we are in the middle of a HOOK, so dns WILL BE reloaded for this domain
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* Delete a domain from OpenDKIM configuration
|
||||
*/
|
||||
function dkim_del($domain,$uid) {
|
||||
$target_dir = "/etc/opendkim/keys/$domain";
|
||||
if (file_exists($target_dir)) {
|
||||
$this->shouldreloaddkim=true;
|
||||
@unlink("$target_dir/alternc_private");
|
||||
@unlink("$target_dir/alternc.txt");
|
||||
@rmdir($target_dir);
|
||||
del_line_from_file("/etc/opendkim/KeyTable","alternc._domainkey.".$domain." ".$domain.":alternc:/etc/opendkim/keys/".$domain."/alternc.private");
|
||||
del_line_from_file("/etc/opendkim/SigningTable",$domain." alternc._domainkey.".$domain);
|
||||
}
|
||||
$db->query("DELETE FROM sub_domaines WHERE domaine=? AND sub='alternc._domainkey';",array($domain));
|
||||
// No need to do DNS_ACTION="UPDATE" => we are in the middle of a HOOK
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
/**
|
||||
* return the content of the TXT information to be added into the DB for DKIM subdomains
|
||||
* @param $domain string the name of the domain name
|
||||
* @return string the TXT entry (without quotes)
|
||||
* or false if an error occurred
|
||||
**/
|
||||
function dkim_get_entry($domain) {
|
||||
global $msg;
|
||||
$key=file_get_contents("/etc/opendkim/keys/".$domain."/alternc.txt");
|
||||
// easy: monoline key
|
||||
if (preg_match('#alternc._domainkey IN TXT "(.*)"#',$key,$mat)) {
|
||||
return $mat[1];
|
||||
} else {
|
||||
// Need to parse a multiligne key:
|
||||
$inkey=false; $result="";
|
||||
$lines=explode("\n",$key);
|
||||
foreach($lines as $line) {
|
||||
if (preg_match('#alternc._domainkey\s+IN\s+TXT\s+\( "(.*)"#',$line,$mat)) {
|
||||
$result.=$mat[1]; $inkey=true; continue;
|
||||
}
|
||||
if ($inkey && preg_match('#^\s*"(.*)"\s*\)#',$line,$mat)) {
|
||||
$result.=$mat[1]; $inkey=false; break;
|
||||
}
|
||||
if ($inkey && preg_match('#^\s*"(.*)"\s*$#',$line,$mat)) {
|
||||
$result.=$mat[1]; $inkey=true; continue;
|
||||
}
|
||||
}
|
||||
if ($result)
|
||||
return $result;
|
||||
}
|
||||
$msg->debug("mail","dkim_get_entry($domain) failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// @TODO hook after reloading DNS zones => if necessary, restart opendkim
|
||||
|
||||
} /* Class m_mail */
|
||||
|
|
|
@ -372,7 +372,34 @@ INSTR(CONCAT(sd.sub,IF(sd.sub!='','.',''),sd.domaine),'.')+1))=?
|
|||
return $db->Record;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/** Return paths to certificate, key, and chain for a certificate
|
||||
* given it's ID.
|
||||
* @param $id integer the certificate by id
|
||||
* @return array cert, key, chain (not mandatory) with full path.
|
||||
*/
|
||||
function get_certificate_path($id) {
|
||||
global $db, $msg, $cuid;
|
||||
$msg->log("ssl", "get_certificate_path",$id);
|
||||
$id = intval($id);
|
||||
$db->query("SELECT id FROM certificates WHERE id=?;",array($id));
|
||||
if (!$db->next_record()) {
|
||||
$msg->raise("ERROR","ssl", _("Can't find this Certificate"));
|
||||
// Return cert 0 info :)
|
||||
$id=0;
|
||||
}
|
||||
$chain=self::KEY_REPOSITORY."/".floor($id/1000)."/".$id.".chain";
|
||||
if (!file_exists($chain))
|
||||
$chain=false;
|
||||
|
||||
return array(
|
||||
"cert" => self::KEY_REPOSITORY."/".floor($id/1000)."/".$id.".pem",
|
||||
"key" => self::KEY_REPOSITORY."/".floor($id/1000)."/".$id.".key",
|
||||
"chain" => $chain
|
||||
);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/** Return all the valid certificates that can be used for a specific FQDN
|
||||
* return the list of certificates by order of preference
|
||||
|
@ -612,6 +639,34 @@ SELECT ?,?,?, FROM_UNIXTIME(?), FROM_UNIXTIME(?), ?, ?, sslcsr FROM certificate
|
|||
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/** Launched by hosting_functions.sh launched by update_domaines.sh
|
||||
* Action may be create/postinst/delete/enable/disable
|
||||
* Change the template for this domain name to have the proper CERTIFICATE
|
||||
* An algorithm determine the best possible certificate, which may be a BAD one
|
||||
* (like a generic self-signed for localhost as a last chance)
|
||||
*/
|
||||
public function hook_updatedomains_web_before($subdomid) {
|
||||
global $db, $msg, $dom;
|
||||
$msg->log("ssl", "hook_updatedomains_web_before($subdomid)");
|
||||
|
||||
$db->query("SELECT sd.*, dt.only_dns, dt.has_https_option, m.login FROM domaines_type dt, sub_domaines sd LEFT JOIN membres m ON m.uid=sd.compte WHERE dt.name=sd.type AND sd.web_action!='OK' AND id=?;",array($subdomid));
|
||||
$db->next_record();
|
||||
$subdom=$db->Record;
|
||||
$domtype=$dom->domains_type_get($subdom["type"]);
|
||||
// the domain type must be a "dns_only=false" one:
|
||||
if ($domtype["only_dns"]==true) {
|
||||
return; // nothing to do : this domain type does not involve Vhosts
|
||||
}
|
||||
$subdom["fqdn"]=$subdom["sub"].(($subdom["sub"])?".":"").$subdom["domaine"];
|
||||
|
||||
list($cert) = $this->get_valid_certs($subdom["fqdn"], $subdom["provider"]);
|
||||
$this->write_cert_file($cert);
|
||||
// Edit certif_hosts:
|
||||
$db->query("UPDATE sub_domaines SET certificate_id=? WHERE id=?;",array($cert["id"], $subdom["id"]));
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
/** Search for the best certificate for a user and a fqdn
|
||||
|
@ -627,7 +682,25 @@ SELECT ?,?,?, FROM_UNIXTIME(?), FROM_UNIXTIME(?), ?, ?, sslcsr FROM certificate
|
|||
|
||||
// get the first good certificate:
|
||||
list($cert) = $this->get_valid_certs($fqdn, $subdom["provider"]);
|
||||
$this->write_cert_file($cert);
|
||||
// we have the files, let's fill the output array :
|
||||
$output=array(
|
||||
"id" => $cert["id"],
|
||||
"crt" => $CRTDIR . "/" . $cert["id"].".pem",
|
||||
"key" => $CRTDIR . "/" . $cert["id"].".key",
|
||||
);
|
||||
if (file_exists($CRTDIR . "/" . $cert["id"].".chain")) {
|
||||
$output["chain"] = $CRTDIR . "/" . $cert["id"].".chain";
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/** Write certificate file into KEY_REPOSITORY
|
||||
* @param $cert array an array with ID sslcrt sslkey sslchain
|
||||
*/
|
||||
function write_cert_file($cert) {
|
||||
// we split the certificates by 1000
|
||||
$CRTDIR = self::KEY_REPOSITORY . "/" . floor($cert["id"]/1000);
|
||||
@mkdir($CRTDIR,0750,true);
|
||||
|
@ -659,16 +732,6 @@ SELECT ?,?,?, FROM_UNIXTIME(?), FROM_UNIXTIME(?), ?, ?, sslcsr FROM certificate
|
|||
chmod($CRTDIR . "/" . $cert["id"].".chain",0640);
|
||||
}
|
||||
}
|
||||
// we have the files, let's fill the output array :
|
||||
$output=array(
|
||||
"id" => $cert["id"],
|
||||
"crt" => $CRTDIR . "/" . $cert["id"].".pem",
|
||||
"key" => $CRTDIR . "/" . $cert["id"].".key",
|
||||
);
|
||||
if (file_exists($CRTDIR . "/" . $cert["id"].".chain")) {
|
||||
$output["chain"] = $CRTDIR . "/" . $cert["id"].".chain";
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|||
0 5 * * * alterncpanel /usr/lib/alternc/sqlbackup.sh -t daily
|
||||
0 4 * * 0 alterncpanel /usr/lib/alternc/sqlbackup.sh -t weekly
|
||||
|
||||
# Every 5 minutes, spool waiting domain changes
|
||||
*/5 * * * * root /usr/lib/alternc/update_domains.sh
|
||||
# Every minute, spool waiting domain changes
|
||||
* * * * * root /usr/lib/alternc/update_domains.php
|
||||
|
||||
# Every 5 minutes, do mails actions
|
||||
*/5 * * * * root /usr/lib/alternc/update_mails.sh
|
||||
|
|
|
@ -42,8 +42,9 @@ case "$1" in
|
|||
|
||||
# corriger les permissions du chroot
|
||||
mkdir -p /var/spool/postfix/var/run/saslauthd || true
|
||||
dpkg-statoverride --quiet --update --add root sasl 710 /var/spool/postfix/var/run/saslauthd || true
|
||||
|
||||
if ! dpkg-statoverride --list /var/spool/postfix/var/run/saslauthd >/dev/null ; then
|
||||
dpkg-statoverride --quiet --update --add root sasl 710 /var/spool/postfix/var/run/saslauthd || true
|
||||
fi
|
||||
|
||||
db_get "alternc/alternc_mail"
|
||||
VMAIL_HOME="$RET"
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
DocumentRoot /usr/share/alternc/panel/admin
|
||||
ServerName %%fqdn%%
|
||||
|
||||
# Mail autoconfig
|
||||
ServerAlias autoconfig.*
|
||||
ServerAlias autodiscover.*
|
||||
|
||||
RewriteEngine on
|
||||
RewriteRule ^/admin/(.*) /$1 [R=301,L]
|
||||
|
||||
|
@ -17,20 +13,6 @@
|
|||
RewriteEngine On
|
||||
RewriteRule ^webmail /webmail-redirect.php [L]
|
||||
|
||||
# Mail autoconfig
|
||||
RewriteRule ^/mail/mailautoconfig.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^/mail/config-v1.1.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^mail/mailautoconfig.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^mail/config-v1.1.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^/autodiscover/autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/Autodiscover/Autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/Autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^autodiscover/autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^Autodiscover/Autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^Autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
|
||||
|
||||
# will be used to define aliases such as /javascript /webmail /squirrelmail ...
|
||||
IncludeOptional /etc/alternc/apache-panel.d/*.conf
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
|
||||
<VirtualHost *:80>
|
||||
DocumentRoot /usr/share/alternc/panel/admin
|
||||
|
||||
AssignUserId alterncpanel alterncpanel
|
||||
SetEnv LOGIN "0000-panel"
|
||||
|
||||
ServerName %%fqdn%%
|
||||
|
||||
# Mail autoconfig
|
||||
RewriteRule ^/mail/mailautoconfig.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^/mail/config-v1.1.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^mail/mailautoconfig.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^mail/config-v1.1.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^/autodiscover/autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/Autodiscover/Autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/Autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^autodiscover/autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^Autodiscover/Autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^Autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
DocumentRoot /usr/share/alternc/panel/admin
|
||||
|
||||
AssignUserId alterncpanel alterncpanel
|
||||
SetEnv LOGIN "0000-panel"
|
||||
|
||||
ServerName %%fqdn%%
|
||||
|
||||
# Mail autoconfig
|
||||
RewriteRule ^/mail/mailautoconfig.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^/mail/config-v1.1.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^mail/mailautoconfig.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^mail/config-v1.1.xml$ /mailautoconfig_thunderbird.php [L]
|
||||
RewriteRule ^/autodiscover/autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/Autodiscover/Autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/Autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^/autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^autodiscover/autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^Autodiscover/Autodiscover.xml$ /mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^Autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
RewriteRule ^autodiscover.xml$ mailautoconfig_outlook.php [L]
|
||||
|
||||
SSLEngine On
|
||||
SSLCertificateFile %%CRT%%
|
||||
SSLCertificateKeyFile %%KEY%%
|
||||
%%CHAINLINE%%
|
||||
|
||||
</VirtualHost>
|
|
@ -10,6 +10,11 @@
|
|||
RewriteCond %{REQUEST_FILENAME} !/.well-known/acme-challenge/
|
||||
RewriteRule ^/(.*)$ http://%%fqdn%%/$1 [R=301,L]
|
||||
|
||||
SSLEngine On
|
||||
SSLCertificateFile %%CRT%%
|
||||
SSLCertificateKeyFile %%KEY%%
|
||||
%%CHAINLINE%%
|
||||
|
||||
</Virtualhost>
|
||||
|
||||
<VirtualHost *:80>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
acl "allslaves" {
|
||||
{
|
||||
127.0.0.1;
|
||||
::1;
|
||||
//AUTO-SLAVES//
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1 +1 @@
|
|||
zone "@@DOMAINE@@" { type master; file "@@ZONE_FILE@@"; allow-query { any; }; };
|
||||
zone "@@DOMAIN@@" { type master; file "@@ZONE_FILE@@"; allow-query { any; }; };
|
||||
|
|
|
@ -354,9 +354,8 @@ do
|
|||
fi
|
||||
done
|
||||
|
||||
# ensure dovecot, postfix, apache, can access ssl certificates:
|
||||
# ensure dovecot, postfix, can access ssl certificates:
|
||||
adduser dovecot ssl-cert
|
||||
adduser www-data ssl-cert
|
||||
adduser postfix ssl-cert
|
||||
|
||||
run-parts --arg=certificates /usr/lib/alternc/install.d
|
||||
|
|
|
@ -115,7 +115,7 @@ CREATE TABLE IF NOT EXISTS domaines (
|
|||
noerase tinyint(4) NOT NULL default '0',
|
||||
dns_action enum ('OK','UPDATE','DELETE') NOT NULL default 'UPDATE',
|
||||
dns_result varchar(255) not null default '',
|
||||
zonettl int(10) unsigned NOT NULL default '86400',
|
||||
zonettl int(10) unsigned NOT NULL default '3600',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY (domaine)
|
||||
) ENGINE=InnoDB;
|
||||
|
@ -479,8 +479,10 @@ CREATE TABLE IF NOT EXISTS `domaines_type` (
|
|||
PRIMARY KEY ( `name` )
|
||||
) ENGINE=InnoDB COMMENT = 'Type of domains allowed';
|
||||
|
||||
INSERT IGNORE INTO `domaines_type` (name, description, target, entry, compatibility, only_dns, need_dns, advanced, enable) values
|
||||
('vhost', 'Locally hosted', 'DIRECTORY', '%SUB% IN A @@PUBLIC_IP@@', 'txt,defmx,defmx2,mx,mx2', false, false, false, 'ALL'),
|
||||
INSERT IGNORE INTO `domaines_type` (name, description, target, entry, compatibility, only_dns, need_dns, advanced, enable) VALUES
|
||||
('dkim', 'DKIM Key', 'TXT', '%SUB% IN TXT "%TARGET%"', 'txt,defmx,defmx2,mx,mx2,url,ip,ipv6', true, true, true, 'ADMIN'),
|
||||
('autodiscover', 'Email autoconfiguration', 'NONE', '%SUB% IN A @@PUBLIC_IP@@', 'txt,defmx,defmx2,mx,mx2', false, true, true, 'ADMIN'),
|
||||
('vhost', 'Locally hosted', 'DIRECTORY', '%SUB% IN A @@PUBLIC_IP@@', 'txt,defmx,defmx2,mx,mx2', false, false, false, 'ALL'),
|
||||
('url', 'URL redirection', 'URL', '%SUB% IN A @@PUBLIC_IP@@', 'txt,defmx,defmx2', false, false, false, 'ALL'),
|
||||
('ip', 'IPv4 redirect', 'IP', '%SUB% IN A %TARGET%', 'url,ip,ipv6,txt,mx,mx2,defmx,defmx2', true, true, false, 'ALL'),
|
||||
('ipv6', 'IPv6 redirect', 'IPV6', '%SUB% IN AAAA %TARGET%', 'ip,ipv6,txt,mx,mx2,defmx,defmx2', true, true, true, 'ALL'),
|
||||
|
@ -793,7 +795,6 @@ CREATE TABLE IF NOT EXISTS `certificates` (
|
|||
|
||||
|
||||
|
||||
-- make it re-exec-proof
|
||||
DELETE FROM alternc_status WHERE name='alternc_version';
|
||||
INSERT INTO alternc_status SET name='alternc_version',value='3.5.0.1.sql';
|
||||
-- make it re-exec-proof -- BUT don't overwrite existing value !
|
||||
INSERT IGNORE INTO alternc_status SET name='alternc_version',value='3.5.0.1.sql';
|
||||
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
-- upgrade from 3.4.10 and 3.4.11 (a bug prevented them to be inserted :/ )
|
||||
|
||||
-- migrating DKIM to be inside sub_domaines table
|
||||
INSERT IGNORE INTO `domaines_type` (name, description, target, entry, compatibility, only_dns, need_dns, advanced, enable) VALUES
|
||||
('dkim', 'DKIM Key', 'TXT', '%SUB% IN TXT "%TARGET%"', 'txt,defmx,defmx2,mx,mx2,url,ip,ipv6', true, true, true, 'ADMIN');
|
||||
-- migrating AUTODISCOVER / AUTOCONF to be inside sub_domaines table
|
||||
INSERT IGNORE INTO `domaines_type` (name, description, target, entry, compatibility, only_dns, need_dns, advanced, enable) VALUES
|
||||
('autodiscover', 'Email autoconfiguration', 'NONE', '%SUB% IN A @@PUBLIC_IP@@', 'txt,defmx,defmx2,mx,mx2', false, true, true, 'ADMIN');
|
||||
|
||||
|
||||
-- upgrade from 3.4.10 and 3.4.11 (a bug prevented them to be inserted :/ )
|
||||
ALTER TABLE mailbox MODIFY `lastlogin` DATETIME NOT NULL DEFAULT 0;
|
||||
ALTER TABLE mailbox ADD `lastloginsasl` DATETIME NOT NULL DEFAULT 0 AFTER `lastlogin`;
|
||||
ALTER TABLE `domaines` MODIFY `zonettl` INT(10) UNSIGNED NOT NULL default '3600';
|
||||
|
||||
ALTER TABLE `membres` MODIFY `pass` varchar(255);
|
||||
ALTER TABLE `ftpusers` MODIFY `encrypted_password` varchar(255);
|
||||
-- upgrade to better hashes ($6$, 20000 loops) in membres and ftpusers
|
||||
ALTER TABLE `membres` MODIFY `pass` VARCHAR(255);
|
||||
ALTER TABLE `ftpusers` MODIFY `encrypted_password` VARCHAR(255);
|
||||
|
||||
-- upgrade to merge alternc-ssl into alternc + change the way we work on SSL
|
||||
|
||||
DROP TABLE IF EXISTS `certif_alias`;
|
||||
|
||||
ALTER TABLE `certificates`
|
||||
|
@ -28,7 +37,8 @@ ALTER TABLE `domaines_type`
|
|||
UPDATE `domaines_type` SET `has_https_option`=1 WHERE name='vhost';
|
||||
|
||||
-- Backport old certif_hosts data to sub_domaines
|
||||
UPDATE `sub_domaines` LEFT JOIN `certif_hosts` ON `sub_domaines`.`id` = `certif_hosts`.`sub` SET `sub_domaines`.`certificate_id` = `certif_hosts`.`certif` WHERE 1;
|
||||
UPDATE `sub_domaines` LEFT JOIN `certif_hosts` ON `sub_domaines`.`id` = `certif_hosts`.`sub`
|
||||
SET `sub_domaines`.`certificate_id` = `certif_hosts`.`certif`;
|
||||
DROP TABLE IF EXISTS `certif_hosts`;
|
||||
|
||||
-- Set https status (http,https,both)
|
||||
|
@ -37,21 +47,22 @@ UPDATE `sub_domaines` SET `https` = "both" WHERE `type` LIKE '%-mixssl' AND http
|
|||
UPDATE `sub_domaines` SET `https` = "http" WHERE https = '';
|
||||
UPDATE `sub_domaines` SET `type` = REPLACE(`type`,'-ssl','');
|
||||
UPDATE `sub_domaines` SET `type` = REPLACE(`type`,'-mixssl','');
|
||||
-- Disable https status when domains_type don't provide this
|
||||
UPDATE `sub_domaines` SET `https` = '' WHERE type IN (select name FROM domaines_type WHERE has_https_option = 0);
|
||||
-- Disable https status when domains_type don't use it
|
||||
UPDATE `sub_domaines` SET `https` = '' WHERE type IN (SELECT name FROM domaines_type WHERE has_https_option = 0);
|
||||
|
||||
-- When two sudomain exists, we consider sub_domains with http and https feature
|
||||
-- When two subdomain exists, we consider sub_domains with http and https feature
|
||||
UPDATE sub_domaines AS sd INNER JOIN
|
||||
(SELECT MIN(id) id FROM `sub_domaines` GROUP BY domaine,sub,type HAVING count(id) > 1) sd1
|
||||
ON sd.id = sd1.id
|
||||
SET `https` = "both";
|
||||
-- Delete duplicate lines
|
||||
DELETE sd1 FROM sub_domaines sd1, sub_domaines sd2 WHERE sd1.id > sd2.id AND sd1.domaine = sd2.domaine AND sd1.sub = sd2.sub AND sd1.type = sd2.type AND sd1.https <> '' AND sd2.https <> '';
|
||||
DELETE sd1 FROM sub_domaines sd1, sub_domaines sd2
|
||||
WHERE sd1.id > sd2.id AND sd1.domaine = sd2.domaine AND sd1.sub = sd2.sub AND sd1.type = sd2.type
|
||||
AND sd1.https <> '' AND sd2.https <> '';
|
||||
|
||||
-- we need to regenerate all vhost, they will be by AlternC.install
|
||||
-- UPDATE `sub_domaines` SET `web_action` = 'UPDATE';
|
||||
|
||||
|
||||
-- change some variable names :
|
||||
|
||||
UPDATE variable
|
||||
|
@ -72,6 +83,6 @@ DELETE FROM variable WHERE name IN (
|
|||
'ftp_human_name'
|
||||
);
|
||||
|
||||
-- we'd like to prepare IPv6 ;)
|
||||
-- we'd like to prepare for IPv6 ;)
|
||||
ALTER TABLE `domaines_type` CHANGE `entry` `entry` TEXT DEFAULT '';
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/php -q
|
||||
<?php
|
||||
|
||||
// we don't check our AlternC session
|
||||
if(!chdir("/usr/share/alternc/panel"))
|
||||
exit(1);
|
||||
require("/usr/share/alternc/panel/class/config_nochk.php");
|
||||
|
||||
$db->query("SELECT * FROM domaines WHERE gesdns=1 AND gesmx=1;");
|
||||
$add=array();
|
||||
while ($db->next_record()) {
|
||||
$add[$db->Record["domaine"]]=$db->Record["compte"];
|
||||
}
|
||||
foreach($add as $domain => $id) {
|
||||
// Convert DKIM keys into SUB_DOMAINES table
|
||||
if (file_exists("/etc/opendkim/keys/".$domain."/alternc.txt")) {
|
||||
$dkim_key = $mail->dkim_get_entry($domain);
|
||||
if ($dkim_key) {
|
||||
// Add subdomain dkim entry
|
||||
$db->query("INSERT INTO sub_domaines
|
||||
SET compte=?, domaine=?, sub='@', valeur=?, type='dkim', web_action='OK', web_result=0, enable='ENABLED';",
|
||||
array($id, $domain, $dkim_key)
|
||||
);
|
||||
// Alternc.INSTALL WILL reload DNS zones anyway, so fear not we don't set dns_action="RELOAD" here.
|
||||
}
|
||||
}
|
||||
// Convert autodiscover into SUB_DOMAINES table
|
||||
$db->query("INSERT INTO sub_domaines
|
||||
SET compte=?, domaine=?, sub='@', valeur='', type='autodiscover', web_action='UPDATE', web_result=0, enable='ENABLED';",
|
||||
array($id, $domain)
|
||||
);
|
||||
}
|
||||
|
|
@ -690,101 +690,6 @@ class m_domTest extends TestCase
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::generation_parameters
|
||||
* @todo Implement testGeneration_parameters().
|
||||
*/
|
||||
public function testGeneration_parameters()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::generation_domains_type
|
||||
* @todo Implement testGeneration_domains_type().
|
||||
*/
|
||||
public function testGeneration_domains_type()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::generate_conf_oldhook
|
||||
* @todo Implement testGenerate_conf_oldhook().
|
||||
*/
|
||||
public function testGenerate_conf_oldhook()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::generate_apacheconf
|
||||
* @todo Implement testGenerate_apacheconf().
|
||||
*/
|
||||
public function testGenerate_apacheconf()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::generation_todo
|
||||
* @todo Implement testGeneration_todo().
|
||||
*/
|
||||
public function testGeneration_todo()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::subdomain_modif_are_done
|
||||
* @todo Implement testSubdomain_modif_are_done().
|
||||
*/
|
||||
public function testSubdomain_modif_are_done()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::set_dns_action
|
||||
* @todo Implement testSet_dns_action().
|
||||
*/
|
||||
public function testSet_dns_action()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::set_dns_result
|
||||
* @todo Implement testSet_dns_result().
|
||||
*/
|
||||
public function testSet_dns_result()
|
||||
{
|
||||
// Remove the following lines when you implement this test.
|
||||
$this->markTestIncomplete(
|
||||
'This test has not been implemented yet.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers m_dom::get_problems
|
||||
|
|
|
@ -1,223 +0,0 @@
|
|||
#!/bin/bash
|
||||
# dns.sh next-gen by Fufroma
|
||||
|
||||
# Init some vars
|
||||
. /etc/alternc/local.sh
|
||||
. /usr/lib/alternc/functions.sh
|
||||
|
||||
# Init some other vars
|
||||
ZONE_TEMPLATE="/etc/alternc/templates/bind/templates/zone.template"
|
||||
NAMED_TEMPLATE="/etc/alternc/templates/bind/templates/named.template"
|
||||
NAMED_CONF="/var/lib/alternc/bind/automatic.conf"
|
||||
RNDC="/usr/sbin/rndc"
|
||||
|
||||
dns_zone_file() {
|
||||
echo "/var/lib/alternc/bind/zones/$1"
|
||||
}
|
||||
|
||||
dns_is_locked() {
|
||||
local domain=$1
|
||||
if [ ! -r "$(dns_zone_file $domain)" ] ; then
|
||||
return 1
|
||||
fi
|
||||
grep "LOCKED:YES" "$(dns_zone_file $domain)"
|
||||
return $?
|
||||
}
|
||||
|
||||
dns_get_serial() {
|
||||
local domain=$1
|
||||
local serial=$(( $(grep "; serial" $(dns_zone_file $domain) 2>/dev/null|awk '{ print $1;}') + 1 ))
|
||||
local serial2=$(date +%Y%m%d00)
|
||||
if [ $serial -gt $serial2 ] ; then
|
||||
echo $serial
|
||||
else
|
||||
echo $serial2
|
||||
fi
|
||||
}
|
||||
|
||||
dns_get_zonettl() {
|
||||
local domain=$1
|
||||
local zonettl=$(
|
||||
$MYSQL_DO "SELECT zonettl FROM domaines d WHERE d.domaine='$domain';"
|
||||
)
|
||||
# default value
|
||||
if [ "$zonettl" == "" ] ; then
|
||||
zonettl="86400"
|
||||
fi
|
||||
if [ "$zonettl" -eq "0" ] ; then
|
||||
zonettl="86400"
|
||||
fi
|
||||
echo $zonettl
|
||||
}
|
||||
|
||||
dns_chmod() {
|
||||
local domain=$1
|
||||
chgrp bind $(dns_zone_file $domain)
|
||||
chmod 640 $(dns_zone_file $domain)
|
||||
return 0
|
||||
}
|
||||
|
||||
dns_named_conf() {
|
||||
local domain=$1
|
||||
|
||||
if [ ! -f "$(dns_zone_file $domain)" ] ; then
|
||||
echo Error : no file $(dns_zone_file $domain)
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Add the entry
|
||||
grep -q "\"${domain/./\\.}\"" "$NAMED_CONF"
|
||||
if [ $? -ne 0 ] ; then
|
||||
local tempo=$(cat "$NAMED_TEMPLATE")
|
||||
tempo=${tempo/@@DOMAINE@@/$domain}
|
||||
tempo=${tempo/@@ZONE_FILE@@/$(dns_zone_file $domain)}
|
||||
echo $tempo >> "$NAMED_CONF"
|
||||
# Kindly ask Bind to reload its configuration
|
||||
# (the zone file is already created and populated)
|
||||
$RNDC reconfig
|
||||
# Hook it !
|
||||
run-parts --arg=dns_reconfig --arg="$domain" /usr/lib/alternc/reload.d
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
dns_delete() {
|
||||
local domain=$1
|
||||
|
||||
# Delete the zone file
|
||||
if [ -w "$(dns_zone_file $domain)" ] ; then
|
||||
rm -f "$(dns_zone_file $domain)"
|
||||
fi
|
||||
|
||||
local reg_domain=${domain/./\\.}
|
||||
|
||||
# Remove from the named conf
|
||||
local file=$(cat "$NAMED_CONF")
|
||||
echo -e "$file" |grep -v "\"$reg_domain\"" > "$NAMED_CONF"
|
||||
|
||||
# Remove the conf from openDKIM
|
||||
rm -rf "/etc/opendkim/keys/$domain"
|
||||
grep -v "^$reg_domain\$" /etc/opendkim/TrustedHosts >/etc/opendkim/TrustedHosts.alternc-tmp && mv /etc/opendkim/TrustedHosts.alternc-tmp /etc/opendkim/TrustedHosts
|
||||
grep -v "^alternc\._domainkey\.$reg_domain " /etc/opendkim/KeyTable >/etc/opendkim/KeyTable.alternc-tmp && mv /etc/opendkim/KeyTable.alternc-tmp /etc/opendkim/KeyTable
|
||||
grep -v "^$domain alternc\._domainkey\.$reg_domain\$" /etc/opendkim/SigningTable >/etc/opendkim/SigningTable.alternc-tmp && mv /etc/opendkim/SigningTable.alternc-tmp /etc/opendkim/SigningTable
|
||||
|
||||
# Ask the dns server for restart
|
||||
$RNDC reconfig
|
||||
# Hook it !
|
||||
run-parts --arg=dns_reconfig --arg="$domain" /usr/lib/alternc/reload.d
|
||||
}
|
||||
|
||||
# DNS regenerate
|
||||
dns_regenerate() {
|
||||
local domain=$1
|
||||
local manual_tag=";;; END ALTERNC AUTOGENERATE CONFIGURATION"
|
||||
local zone_file=$(dns_zone_file $domain)
|
||||
|
||||
# Check if locked
|
||||
dns_is_locked "$domain"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "DNS $domain LOCKED"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get the serial number if there is one
|
||||
local serial=$(dns_get_serial "$domain")
|
||||
|
||||
# Get the zone ttl
|
||||
local zonettl=$(dns_get_zonettl "$domain")
|
||||
|
||||
# Generate the headers with the template
|
||||
local file=$(cat "$ZONE_TEMPLATE")
|
||||
|
||||
# Add the entry
|
||||
file=$(
|
||||
echo -e "$file"
|
||||
$MYSQL_DO "select distinct 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.domaine='$domain' and sd.enable in ('ENABLE', 'ENABLED') order by entry ;"
|
||||
)
|
||||
|
||||
##### Mail autodetect for thunderbird / outlook - START
|
||||
# If $file contain DEFAULT_MX
|
||||
if [ ! -z "$(echo -e "$file" |egrep 'DEFAULT_MX' )" ] ; then
|
||||
# If $file ! contain autoconfig -> add entry
|
||||
if [ -z "$(echo -e "$file" |egrep '^autoconfig' )" ] ; then
|
||||
file="$(echo -e "$file" ; echo -e "autoconfig IN CNAME $FQDN.\n")"
|
||||
fi
|
||||
# if $file ! contain autodiscover -> add entry
|
||||
if [ -z "$(echo -e "$file" |egrep '^autodiscover' )" ] ; then
|
||||
file="$(echo -e "$file" ; echo -e "autodiscover IN CNAME $FQDN.\n")"
|
||||
fi
|
||||
fi # End if containt DEFAULT_MX
|
||||
##### Mail autodetect for thunderbird / outlook - END
|
||||
|
||||
##### OpenDKIM signature management - START
|
||||
# If $file contain DEFAULT_MX
|
||||
if [ ! -z "$(echo -e "$file" |egrep 'DEFAULT_MX' )" ] ; then
|
||||
# If necessary, we generate the key:
|
||||
if [ ! -d "/etc/opendkim/keys/$domain" ] ; then
|
||||
mkdir -p "/etc/opendkim/keys/$domain"
|
||||
|
||||
pushd "/etc/opendkim/keys/$domain" >/dev/null
|
||||
opendkim-genkey -r -d "$domain" -s "alternc"
|
||||
chown opendkim:opendkim alternc.private
|
||||
popd
|
||||
|
||||
local reg_domain=${domain/./\\.}
|
||||
|
||||
grep -q "^$reg_domain\$" /etc/opendkim/TrustedHosts || echo "$domain" >>/etc/opendkim/TrustedHosts
|
||||
grep -q "^alternc\._domainkey\.$reg_domain " /etc/opendkim/KeyTable || echo "alternc._domainkey.$domain $domain:alternc:/etc/opendkim/keys/$domain/alternc.private" >> /etc/opendkim/KeyTable
|
||||
grep -q "^$domain alternc\._domainkey\.$reg_domain\$" /etc/opendkim/SigningTable || echo "$domain alternc._domainkey.$domain" >> /etc/opendkim/SigningTable
|
||||
fi
|
||||
# we add alternc._domainkey with the proper key
|
||||
|
||||
if [ -r "/etc/opendkim/keys/$domain/alternc.txt" ] ; then
|
||||
file="$(echo -e "$file" ; cat "/etc/opendkim/keys/$domain/alternc.txt")"
|
||||
fi
|
||||
fi
|
||||
##### OpenDKIM signature management - END
|
||||
|
||||
# Replace the vars by their values
|
||||
# Here we can add dynamic value for the default MX
|
||||
file=$( echo -e "$file" | sed -e "
|
||||
s/%%fqdn%%/$FQDN/g;
|
||||
s/%%ns1%%/$NS1_HOSTNAME/g;
|
||||
s/%%ns2%%/$NS2_HOSTNAME/g;
|
||||
s/%%DEFAULT_MX%%/$DEFAULT_MX/g;
|
||||
s/%%DEFAULT_SECONDARY_MX%%/$DEFAULT_SECONDARY_MX/g;
|
||||
s/@@fqdn@@/$FQDN/g;
|
||||
s/@@ns1@@/$NS1_HOSTNAME/g;
|
||||
s/@@ns2@@/$NS2_HOSTNAME/g;
|
||||
s/@@DEFAULT_MX@@/$DEFAULT_MX/g;
|
||||
s/@@DEFAULT_SECONDARY_MX@@/$DEFAULT_SECONDARY_MX/g;
|
||||
s/@@DOMAINE@@/$domain/g;
|
||||
s/@@SERIAL@@/$serial/g;
|
||||
s/@@PUBLIC_IP@@/$PUBLIC_IP/g;
|
||||
s/@@ZONETTL@@/$zonettl/g;
|
||||
" )
|
||||
|
||||
# Add the manually entered resource records (after the special tag ;;; END ALTERNC AUTOGENERATE CONFIGURATION)
|
||||
if [ -r "$zone_file" ] ; then
|
||||
file=$(
|
||||
echo -e "$file"
|
||||
grep -A 10000 "$manual_tag" "$zone_file"
|
||||
)
|
||||
fi
|
||||
# Add the special tag at the end of the zone, if it is not here yet:
|
||||
if ! echo -e "$file" | grep -q "$manual_tag"
|
||||
then
|
||||
file=$(echo -e "$file"; echo "$manual_tag")
|
||||
fi
|
||||
|
||||
# Init the file
|
||||
echo -e "$file" > "$zone_file"
|
||||
|
||||
# And set his rights
|
||||
dns_chmod $domain
|
||||
# Add it to named conf
|
||||
dns_named_conf $domain
|
||||
|
||||
# Hook it !
|
||||
run-parts --arg=dns_reload_zone --arg="$domain" /usr/lib/alternc/reload.d
|
||||
|
||||
# ask bind to reload the zone
|
||||
$RNDC reload $domain
|
||||
}
|
|
@ -1,225 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
. /usr/lib/alternc/functions.sh
|
||||
|
||||
TEMPLATE_DIR="/etc/alternc/templates/apache2"
|
||||
HOSTING_DIR="/etc/alternc/functions_hosting"
|
||||
|
||||
HTML_HOME="$ALTERNC_HTML"
|
||||
VHOST_DIR="/var/lib/alternc/apache-vhost"
|
||||
|
||||
launch_hooks() {
|
||||
local ACTION=$1
|
||||
|
||||
if [ ! $2 ] ; then
|
||||
# If no VTYPE specified
|
||||
return 0
|
||||
fi
|
||||
|
||||
local VTYPE=$2
|
||||
|
||||
EXITCODE=0
|
||||
if [ -x "$HOSTING_DIR/hosting_$VTYPE.sh" ] ; then
|
||||
# If a specific script exist for this VTYPE,
|
||||
# we launch it, and return his return code
|
||||
"$HOSTING_DIR/hosting_$VTYPE.sh" "$1" "$2" "$3" "$4"
|
||||
EXITCODE=$?
|
||||
fi
|
||||
# also launch ssl update domains hook
|
||||
/usr/lib/alternc/update_certs.sh "$1" "$2" "$3" "$4"
|
||||
|
||||
# No specific script, return 0
|
||||
return "$EXITCODE"
|
||||
}
|
||||
|
||||
host_conffile() {
|
||||
# Return the absolute path of a conf file for a FQDN
|
||||
local FQDN="$1"
|
||||
local U_ID=$(get_uid_by_domain "$FQDN")
|
||||
local CONFFILE="$VHOST_DIR/${U_ID:(-1)}/$U_ID/$FQDN.conf"
|
||||
echo $CONFFILE
|
||||
return 0
|
||||
}
|
||||
|
||||
host_create() {
|
||||
# Function to create a vhost for a website
|
||||
# First, it look if there is a special file for
|
||||
# this type of vhost
|
||||
# If there isn't, it use the default function
|
||||
# and the template file provided
|
||||
|
||||
local VTYPE="$1"
|
||||
|
||||
launch_hooks "create" "$1" "$2" "$3" "$4"
|
||||
if [ $? -gt 10 ] ; then
|
||||
# If the hooks return a value > 10
|
||||
# it's mean we do not continue the
|
||||
# "default" actions
|
||||
return $?
|
||||
fi
|
||||
|
||||
# There is no special script, I use the standart template
|
||||
# If I do not found template manualy define, I look
|
||||
# If there is an existing template with the good name
|
||||
|
||||
# First, usefull vars. Some may be empty or false, it's
|
||||
# OK, it will be solve in the "case" below
|
||||
local FQDN=$2
|
||||
local MAIL_ACCOUNT=$3
|
||||
local REDIRECT=$4 # Yes, TARGET_DIR and REDIRECT are the same
|
||||
local TARGET_DIR=$4 # It's used by different template
|
||||
local U_ID=$(get_uid_by_domain "$FQDN")
|
||||
local G_ID="$U_ID"
|
||||
local USER=$(get_account_by_domain $FQDN)
|
||||
local user_letter=`print_user_letter "$USER"`
|
||||
local DOCUMENT_ROOT="${HTML_HOME}/${user_letter}/${USER}$TARGET_DIR"
|
||||
local ACCOUNT_ROOT="${HTML_HOME}/${user_letter}/${USER}/"
|
||||
local FILE_TARGET=$(host_conffile "$FQDN")
|
||||
|
||||
# In case VTYPE don't have the same name as the template file,
|
||||
# here we can define it
|
||||
local TEMPLATE=''
|
||||
case $VTYPE in
|
||||
# "example")
|
||||
# TEMPLATE="$TEMPLATE_DIR/an-example.conf"
|
||||
# ;;
|
||||
*)
|
||||
# No template found, look if there is some in the
|
||||
# template dir
|
||||
[ -r "$TEMPLATE_DIR/$VTYPE" ] && TEMPLATE="$TEMPLATE_DIR/$VTYPE"
|
||||
[ ! "$TEMPLATE" ] && [ -r "$TEMPLATE_DIR/$VTYPE.conf" ] && TEMPLATE="$TEMPLATE_DIR/$VTYPE.conf"
|
||||
;;
|
||||
esac
|
||||
|
||||
# If TEMPLATE is empty, stop right here
|
||||
[ ! "$TEMPLATE" ] && return 6
|
||||
|
||||
# Forbid generation for website with UID/GID == 0
|
||||
if [[ $U_ID == 0 || $G_ID == 0 ]] ; then
|
||||
log_error "Fatal error: update_domains/function_dns/host_create : FQDN = $FQDN - TYPE = $VTYPE - UID = $U_ID - GID = $G_ID . Stopping generation"
|
||||
return 7
|
||||
fi
|
||||
|
||||
# Create a new conf file
|
||||
local TMP_FILE=$(mktemp "/tmp/alternc_host.XXXXXX")
|
||||
cp "$TEMPLATE" "$TMP_FILE"
|
||||
|
||||
# Substitute special characters :
|
||||
FQDN2="`echo $FQDN | sed -e 's/\\\\/\\\\\\\\/g' -e 's/#/\\\\#/g' -e 's/&/\\\\\\&/g'`"
|
||||
DOCUMENT_ROOT2="`echo $DOCUMENT_ROOT | sed -e 's/\\\\/\\\\\\\\/g' -e 's/#/\\\\#/g' -e 's/&/\\\\\\&/g'`"
|
||||
ACCOUNT_ROOT2="`echo $ACCOUNT_ROOT | sed -e 's/\\\\/\\\\\\\\/g' -e 's/#/\\\\#/g' -e 's/&/\\\\\\&/g'`"
|
||||
REDIRECT2="`echo $REDIRECT | sed -e 's/\\\\/\\\\\\\\/g' -e 's/#/\\\\#/g' -e 's/&/\\\\\\&/g'`"
|
||||
USER2="`echo $USER | sed -e 's/\\\\/\\\\\\\\/g' -e 's/#/\\\\#/g' -e 's/&/\\\\\\&/g'`"
|
||||
|
||||
# Put the good value in the conf file
|
||||
sed -i \
|
||||
-e "s#%%LOGIN%%#$USER#g" \
|
||||
-e "s#%%fqdn%%#$FQDN2#g" \
|
||||
-e "s#%%document_root%%#$DOCUMENT_ROOT2#g" \
|
||||
-e "s#%%account_root%%#$ACCOUNT_ROOT2#g" \
|
||||
-e "s#%%redirect%%#$REDIRECT2#g" \
|
||||
-e "s#%%UID%%#$U_ID#g" \
|
||||
-e "s#%%GID%%#$G_ID#g" \
|
||||
-e "s#%%mail_account%%#$MAIL_ACCOUNT#g" \
|
||||
-e "s#%%user%%#$USER2#g" \
|
||||
$TMP_FILE
|
||||
|
||||
## Fix for wildcard
|
||||
if [[ "$FQDN2" == "*."* ]]; then
|
||||
sed -i "s/ServerName/ServerAlias/" $TMP_FILE
|
||||
fi
|
||||
|
||||
# Check if all is right in the conf file
|
||||
# If not, put a debug message
|
||||
# NO : redirect and document_root COULD contains legitimate %% expressions (...)
|
||||
# local ISNOTGOOD=$(grep "%%" "$TMP_FILE")
|
||||
# [ "$ISNOTGOOD" ] && (echo "# There was a probleme in the generation : $ISNOTGOOD" > "$TMP_FILE" ; return 44 )
|
||||
|
||||
# Put the conf file in prod
|
||||
mkdir -p "$(dirname "$FILE_TARGET")"
|
||||
mv -f "$TMP_FILE" "$FILE_TARGET"
|
||||
|
||||
# Execute post-install hooks
|
||||
launch_hooks "postinst" "$1" "$2" "$3" "$4"
|
||||
if [ $? -gt 10 ] ; then
|
||||
# If the hooks return a value > 10
|
||||
# it's mean we do not continue the
|
||||
# "default" actions
|
||||
return $?
|
||||
fi
|
||||
|
||||
# All is quit, we return 0
|
||||
return 0
|
||||
}
|
||||
|
||||
host_disable() {
|
||||
host_change_enable "disable" "$1" "$2" "$3" "$4"
|
||||
}
|
||||
|
||||
host_enable() {
|
||||
host_change_enable "enable" "$1" "$2" "$3" "$4"
|
||||
}
|
||||
|
||||
host_change_enable() {
|
||||
# Function to enable or disable a host
|
||||
local STATE=$1
|
||||
|
||||
# Execute hooks
|
||||
launch_hooks "$1" "$2" "$3" "$4"
|
||||
if [ $? -gt 10 ] ; then
|
||||
# If the hooks return a value > 10
|
||||
# it's mean we do not continue the
|
||||
# "default" actions
|
||||
return $?
|
||||
fi
|
||||
|
||||
local TYPE=$2 # no use here, but one day, maybe... So here he is
|
||||
local FQDN=$3
|
||||
local FENABLED=$(host_conffile "$FQDN")
|
||||
local FDISABLED="$FENABLED-disabled"
|
||||
|
||||
case $STATE in
|
||||
"enable")
|
||||
local SOURCE="$FDISABLED"
|
||||
local TARGET="$FENABLED"
|
||||
;;
|
||||
"disable")
|
||||
local TARGET="$FDISABLED"
|
||||
local SOURCE="$FENABLED"
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -e "$TARGET" ] && [ -e "$SOURCE" ] ; then
|
||||
# If the "target" file do not exist and the "source" file exist
|
||||
mv -f "$SOURCE" "$TARGET"
|
||||
else
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
host_delete() {
|
||||
local VTYPE=$1
|
||||
local FQDN=$2
|
||||
# Execute post-install hooks
|
||||
launch_hooks "delete" "$1" "$2" "$3" "$4"
|
||||
if [ $? -gt 10 ] ; then
|
||||
# If the hooks return a value > 10
|
||||
# it's mean we do not continue the
|
||||
# "default" actions
|
||||
return $?
|
||||
fi
|
||||
|
||||
# Fix of a longstanding BUG: we only DELETE the vhost file if the type is a vhost one !
|
||||
if [ -f "${TEMPLATE_DIR}/${VTYPE}.conf" ]
|
||||
then
|
||||
local FENABLED=$(host_conffile "$FQDN")
|
||||
local FDISABLED="$FENABLED-disabled"
|
||||
|
||||
[ -w "$FENABLED" ] && rm -f "$FENABLED"
|
||||
[ -w "$FDISABLED" ] && rm -f "$FDISABLED"
|
||||
fi
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
#!/usr/bin/php -q
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Generate Apache configuration for AlternC
|
||||
*
|
||||
* To force generation, /launch/generate_apache_conf.php force
|
||||
*
|
||||
* Return the number of vhost modified, return 0 if no action
|
||||
*
|
||||
**/
|
||||
|
||||
require_once("/usr/share/alternc/panel/class/config_nochk.php");
|
||||
ini_set("display_errors", 1);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
FIXME :
|
||||
- add security check
|
||||
*/
|
||||
|
||||
// Check if we can modify Apache conf
|
||||
@touch(ALTERNC_VHOST_FILE);
|
||||
if ( ! is_writable( ALTERNC_VHOST_FILE )) {
|
||||
die("Error: ".ALTERNC_VHOST_FILE." is not writable\n");
|
||||
}
|
||||
|
||||
// Do we need to regenerate apache conf ?
|
||||
$db->query("select count(*) as c from sub_domaines where web_action != 'OK';");
|
||||
if (! $db->next_record()) $nb_todo = 0;
|
||||
$nb_todo = $db->f('c');
|
||||
|
||||
// But, we may have forced it
|
||||
if ( ! in_array('force', $argv) && $nb_todo < 1) {
|
||||
die('0');
|
||||
}
|
||||
|
||||
$todo = $dom->generation_todo();
|
||||
$parameters = $dom->generation_parameters();
|
||||
|
||||
// Generate apache conf
|
||||
$conf = $dom->generate_apacheconf();
|
||||
|
||||
if (! $conf) {
|
||||
die("Error: generate empty configuration\n");
|
||||
}
|
||||
|
||||
// Add some headers
|
||||
$conf2 = "###BEGIN OF ALTERNC AUTO-GENERATED FILE - DO NOT EDIT MANUALLY###
|
||||
# Generation: ".date('Y-m-d H:i:s');
|
||||
|
||||
// Do we need to include manual configuration ?
|
||||
if ( is_dir( ALTERNC_VHOST_MANUALCONF ) ) {
|
||||
$conf2.="\n## Manual VHOST\nInclude ".ALTERNC_VHOST_MANUALCONF."\n" ;
|
||||
} else {
|
||||
$conf2.="\n## Manual VHOST directory missing (".ALTERNC_VHOST_MANUALCONF.")\n" ;
|
||||
}
|
||||
|
||||
$conf2.="\n$conf\n\n###END OF ALTERNC AUTO-GENERATED FILE - DO NOT EDIT MANUALLY###\n";
|
||||
|
||||
// Write the conf !
|
||||
if (! file_put_contents(ALTERNC_VHOST_FILE, $conf2) ) {
|
||||
die("Error: writing content\n");
|
||||
}
|
||||
|
||||
// Update the database to inform that we did the job
|
||||
foreach ( $todo as $taction=>$tlist){
|
||||
foreach ($tlist as $ttype) {
|
||||
foreach($ttype as $tid) {
|
||||
$dom->subdomain_modif_are_done($tid, $taction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hooks !
|
||||
foreach (array('DELETE', 'CREATE', 'UPDATE', 'ENABLE', 'DISABLE') as $y) {
|
||||
if (!isset($todo[$y]) || empty($todo[$y])) continue;
|
||||
$dom->generate_conf_oldhook($y, $todo); // old hooks for compatibility
|
||||
$hooks->invoke("hook_genconf", array($y, $todo[$y], $parameters)); // modern hooks
|
||||
}
|
||||
|
||||
echo $nb_todo;
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#!/usr/bin/php -q
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* Generate Bind configuration for AlternC
|
||||
*
|
||||
* To force generation, /launch/generate_bind_conf.php --force
|
||||
*
|
||||
*
|
||||
**/
|
||||
|
||||
require_once("/usr/share/alternc/panel/class/config_nochk.php");
|
||||
ini_set("display_errors", 1);
|
||||
|
||||
$bind = new system_bind();
|
||||
|
||||
$force = false;
|
||||
if (in_array('--force', $argv)) { // Want to force
|
||||
$force=true;
|
||||
}
|
||||
|
||||
$bind->regenerate_conf($force);
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
. /usr/lib/alternc/functions.sh
|
||||
|
||||
echo "This script will rebuild all web configuration and regenerate DNS."
|
||||
echo "Only files in $VHOST_MANUALCONF will be preserved."
|
||||
echo "Use --force to skip confirmation"
|
||||
|
||||
if [ ! "$1" == "--force" ] ; then
|
||||
|
@ -20,7 +19,6 @@ mysql_query "update domaines set dns_action = 'UPDATE' WHERE dns_action != '
|
|||
|
||||
echo "Now launching update_domains to rebuild."
|
||||
/usr/lib/alternc/update_domains.sh
|
||||
/usr/lib/alternc/generate_bind_conf.php --force
|
||||
|
||||
echo "Finish."
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/php -q
|
||||
<?php
|
||||
|
||||
// bootstrap
|
||||
require_once("/usr/share/alternc/panel/class/config_nochk.php");
|
||||
|
||||
putenv("PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");
|
||||
|
||||
$dom->update_domains();
|
||||
|
|
@ -1,168 +1,5 @@
|
|||
#!/bin/bash
|
||||
# Update domain next-gen by fufroma
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
# This is now done using PHP-only scripting
|
||||
|
||||
for CONFIG_FILE in \
|
||||
/etc/alternc/local.sh \
|
||||
/usr/lib/alternc/functions.sh \
|
||||
/usr/lib/alternc/functions_hosting.sh \
|
||||
/usr/lib/alternc/functions_dns.sh
|
||||
do
|
||||
if [ ! -r "$CONFIG_FILE" ]; then
|
||||
echo "Can't access $CONFIG_FILE."
|
||||
exit 1
|
||||
fi
|
||||
. "$CONFIG_FILE"
|
||||
done
|
||||
|
||||
stop_if_jobs_locked
|
||||
|
||||
# Some vars
|
||||
umask 022
|
||||
LOCK_FILE="/usr/share/alternc/panel/cron.lock" # FIXME doesn't seem clean to be here
|
||||
OLDIFS="$IFS"
|
||||
NEWIFS=" "
|
||||
RELOAD_WEB="$(mktemp /tmp/alternc_reload_web.XXXX)"
|
||||
RELOAD_DNS="$(mktemp /tmp/alternc_reload_dns.XXXX)"
|
||||
B="µµ§§" # Strange letters to make split in query
|
||||
|
||||
# Somes check before start operations
|
||||
if [ `id -u` -ne 0 ]; then
|
||||
log_error "must be launched as root"
|
||||
elif [ -z "$DEFAULT_MX" -o -z "$PUBLIC_IP" ]; then
|
||||
log_error "Bad configuration. Please use: dpkg-reconfigure alternc"
|
||||
elif [ -f "$LOCK_FILE" ]; then
|
||||
process=$(ps f -p `cat "$LOCK_FILE"|tail -1`|tail -1|awk '{print $NF;}')
|
||||
if [ "$(basename $process)" = "$(basename "$0")" ] ; then
|
||||
log_error "last cron unfinished or stale lock file ($LOCK_FILE)."
|
||||
else
|
||||
rm "$LOCK_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# backward compatibility: single-server setup
|
||||
if [ -z "$ALTERNC_SLAVES" ] ; then
|
||||
ALTERNC_SLAVES="localhost"
|
||||
fi
|
||||
|
||||
# We lock the application
|
||||
echo $$ > "$LOCK_FILE"
|
||||
|
||||
echo "" > "$RELOAD_WEB"
|
||||
echo "" > "$RELOAD_DNS"
|
||||
|
||||
# For domains we want to delete completely, make sure all the tags are all right
|
||||
# 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';"
|
||||
|
||||
# Sub_domaines we want to delete
|
||||
# sub_domaines.web_action = delete
|
||||
for sub in $( mysql_query "select concat_ws('$B',lower(sd.type), if(length(sd.sub)>0,concat_ws('.',sd.sub,sd.domaine),sd.domaine)) from sub_domaines sd where web_action ='DELETE';") ; do
|
||||
host_delete ${sub/$B/ }
|
||||
mysql_query "delete from sub_domaines where concat_ws('$B',lower(type), if(length(sub)>0,concat_ws('.',sub,domaine),domaine)) = '$sub' and web_action ='DELETE';"
|
||||
echo 1 > "$RELOAD_WEB"
|
||||
done
|
||||
|
||||
# Sub domaines we want to update
|
||||
# sub_domaines.web_action = update and sub_domains.only_dns = false
|
||||
IFS="$NEWIFS"
|
||||
mysql_query "
|
||||
select concat_ws('$IFS',sd.id, lower(sd.type), if(length(sd.sub)>0,concat_ws('.',sd.sub,sd.domaine),sd.domaine), concat_ws('@',m.login,v.value), sd.valeur )
|
||||
from sub_domaines sd,membres m,variable v
|
||||
where sd.compte=m.uid and sd.web_action ='UPDATE' and v.name='mailname_bounce'
|
||||
;" | while read sdid type domain mail valeur ; do
|
||||
host_create "$type" "$domain" "$mail" "$valeur"
|
||||
mysql_query "update sub_domaines sd set web_action='OK',web_result='$?' where sd.id = '$sdid' ; "
|
||||
echo 1 > "$RELOAD_WEB"
|
||||
done
|
||||
|
||||
# Domaine to enable
|
||||
mysql_query "select concat_ws('$IFS',sd.id, lower(sd.type),if(length(sd.sub)>0,concat_ws('.',sd.sub,sd.domaine),sd.domaine),sd.valeur) from sub_domaines sd where sd.enable ='ENABLE' ;"|while read sdid type domain valeur ; do
|
||||
host_enable "$type" "$domain" "$valeur"
|
||||
mysql_query "update sub_domaines sd set enable='ENABLED' where sd.id = '$sdid' ;"
|
||||
echo 1 > "$RELOAD_WEB"
|
||||
done
|
||||
|
||||
# Domains to disable
|
||||
mysql_query "select concat_ws('$IFS', sd.id, lower(sd.type),if(length(sd.sub)>0,concat_ws('.',sd.sub,sd.domaine),sd.domaine),sd.valeur) from sub_domaines sd where sd.enable ='DISABLE' ;"|while read sdid type domain valeur ; do
|
||||
host_disable "$type" "$domain" "$valeur"
|
||||
mysql_query "update sub_domaines sd set enable='DISABLED' where sd.id = '$sdid' ;"
|
||||
echo 1 > "$RELOAD_WEB"
|
||||
done
|
||||
|
||||
# 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'"
|
||||
echo 1 >"$RELOAD_DNS"
|
||||
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'"
|
||||
echo 1 >"$RELOAD_DNS"
|
||||
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';"
|
||||
echo 1 >"$RELOAD_DNS"
|
||||
done
|
||||
|
||||
if [ ! -z "$(cat "$RELOAD_WEB")" ] ; then
|
||||
|
||||
# Just to encourage user to use THIS directory and not another one
|
||||
test -d "$VHOST_MANUALCONF" || mkdir -p "$VHOST_MANUALCONF"
|
||||
|
||||
# Concat the apaches files
|
||||
tempo=$(mktemp "$VHOST_FILE.XXXXX")
|
||||
|
||||
(
|
||||
echo "###BEGIN OF ALTERNC AUTO-GENERATED FILE - DO NOT EDIT MANUALLY###"
|
||||
find "$VHOST_DIR"/ -mindepth 2 -type f -iname "*.conf" -print0 | xargs -0 cat
|
||||
echo "###END OF ALTERNC AUTO-GENERATED FILE - DO NOT EDIT MANUALLY###"
|
||||
) > "$tempo"
|
||||
|
||||
if [ $? -ne 0 ] ; then
|
||||
log_error " web file concatenation failed"
|
||||
fi
|
||||
touch "$VHOST_FILE"
|
||||
if [ ! -w "$VHOST_FILE" ] ; then
|
||||
log_error "cannot write on $VHOST_FILE"
|
||||
fi
|
||||
mv "$tempo" "$VHOST_FILE"
|
||||
|
||||
# We must reload apache
|
||||
# we assume we run apache on the master
|
||||
/usr/lib/alternc/alternc_reload apache || true
|
||||
# Launch hooks for apache reload
|
||||
run-parts --arg=web_reload /usr/lib/alternc/reload.d
|
||||
fi
|
||||
|
||||
# If we added / edited / deleted at least one dns zone file, we go here in the end:
|
||||
if [ ! -z "$(cat "$RELOAD_DNS")" ] ; then
|
||||
service opendkim restart
|
||||
run-parts --arg=dns_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
|
||||
|
||||
rm -f "$LOCK_FILE" "$RELOAD_ZONES" "$RELOAD_WEB" "$INOTIFY_UPDATE_DOMAIN" "$RELOAD_DNS"
|
||||
|
||||
exit 0
|
||||
/usr/lib/alternc/update_domains.php
|
||||
|
||||
|
|
Loading…
Reference in New Issue