Alternc  latest
Alternc logiel libre pour l'hébergement
m_apache.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  ----------------------------------------------------------------------
5  LICENSE
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License (GPL)
9  as published by the Free Software Foundation; either version 2
10  of the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  To read the license please visit http://www.gnu.org/copyleft/gpl.html
18  ----------------------------------------------------------------------
19 */
20 
21 /**
22  * Manages APACHE 2.4+ vhosts templates in AlternC 3.5+
23  *
24  * @copyright AlternC-Team 2000-2018 https://alternc.com/
25  */
26 class m_apache {
27 
29 
30  // only values allowed for https in subdomaines table.
31  var $httpsmodes=array("http","https","both");
32 
33  // Slave AlternC instances can know the last reload time thanks to this
34  var $reloadfile="/run/alternc/apache-reload";
35  // Where do we find apache template files ?
36  var $templatedir="/etc/alternc/templates/apache2";
37  // Where do we store all Apache vhosts ?
38  var $vhostroot="/var/lib/alternc/apache-vhost/";
39 
40  // launched before any action by updatedomains
42  $this->shouldreload=false;
43  }
44 
45  // launched for each FQDN for which we want a new vhost template
46  function hook_updatedomains_web_add($subdomid) {
47  global $msg,$db,$ssl,$L_FQDN;
48 
49  $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));
50  $db->next_record();
51  $subdom=$db->Record;
52 
53  // security : only AlternC account's UIDs
54  if ($subdom["compte"]<1999) {
55  $msg->raise("ERROR","apache","Subdom ".$subdom["id"]." for domain ".$subdom["sub"].".".$subdom["domaine"]." has id ".$subdom["compte"].". Skipped");
56  return 1;
57  }
58 
59  // search for the template file:
60  $template = $this->templatedir."/".strtolower($subdom["type"]);
61  if ($subdom["has_https_option"] && in_array($subdom["https"],$this->httpsmodes)) {
62  $template.="-".$subdom["https"];
63  }
64  $template.=".conf";
65  if (!is_file($template)) {
66  $msg->raise("ERROR","apache","Template $template not found for subdom ".$subdom["id"]." for domain ".$subdom["sub"].".".$subdom["domaine"].". Skipped");
67  return 1;
68  }
69 
70  $subdom["fqdn"]=$subdom["sub"].(($subdom["sub"])?".":"").$subdom["domaine"];
71  // SSL information $subdom["certificate_id"] may be ZERO => it means "take id 0 which is snakeoil cert"
72  $cert = $ssl->get_certificate_path($subdom["certificate_id"]);
73  if ($cert["chain"]) {
74  $chainline="SSLCertificateChainFile ".$cert["chain"];
75  } else {
76  $chainline="";
77  }
78  // Replace needed vars in template file
79  $tpl=file_get_contents($template);
80  $tpl = strtr($tpl, array(
81  "%%LOGIN%%" => $subdom['login'],
82  "%%fqdn%%" => $subdom['fqdn'],
83  "%%document_root%%" => getuserpath($subdom['login']) . $subdom['valeur'],
84  "%%account_root%%" => getuserpath($subdom['login']),
85  "%%redirect%%" => $subdom['valeur'],
86  "%%UID%%" => $subdom['compte'],
87  "%%GID%%" => $subdom['compte'],
88  "%%mail_account%%" => $subdom['login']."@".$L_FQDN,
89  "%%user%%" => "FIXME",
90  "%%CRT%%" => $cert["cert"],
91  "%%KEY%%" => $cert["key"],
92  "%%CHAINLINE%%" => $chainline,
93  ));
94  // and write the template
95  $confdir = $this->vhostroot."/".substr($subdom["compte"],-1)."/".$subdom["compte"];
96  @mkdir($confdir,0755,true);
97  file_put_contents($confdir."/".$subdom["fqdn"].".conf",$tpl);
98  $this->shouldreload=true;
99 
100  return 0; // shell meaning => OK ;)
101  } // hook_updatedomains_web_add
102 
103 
104  // ------------------------------------------------------------
105  /**
106  * launched for each FQDN for which we want to delete a vhost template
107  */
108  function hook_updatedomains_web_del($subdomid) {
109  global $db,$msg;
110  $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));
111  $db->next_record();
112  $subdom=$db->Record;
113  $confdir = $this->vhostroot."/".substr($subdom["compte"],-1)."/".$subdom["compte"];
114  $deleteme= $subdom["sub"].(($subdom["sub"])?".":"").$subdom["domaine"].".conf";
115  @unlink($confdir."/".$deleteme);
116  $this->shouldreload=true;
117  }
118 
119 
120  // ------------------------------------------------------------
121  /**
122  * launched at the very end of updatedomains
123  */
125  global $msg;
126  if ($this->shouldreload) {
127 
128  // concatenate all files into one
129  $this->concat();
130 
131  // reload apache
132  $ret=0;
133  exec("apache2ctl graceful 2>&1",$out,$ret);
134  touch($this->reloadfile);
135  if ($ret!=0) {
136  $msg->raise("ERROR","apache","Error while reloading apache, error code is $ret\n".implode("\n",$out));
137  } else {
138  $msg->raise("INFO","apache","Apache reloaded");
139  }
140  }
141 
142  }
143 
144  // ------------------------------------------------------------
145  /**
146  * Concatenate all files under $this->vhostroot
147  * into one (mindepth=2 though),
148  * this function is faster than any shell stuff :D
149  */
150  private function concat() {
151  global $msg;
152  $d=opendir($this->vhostroot);
153  $f=fopen($this->vhostroot."/vhosts_all.conf.new","wb");
154  if (!$f) {
155  $msg->raise("FATAL","apache","Can't write vhosts_all file");
156  return false;
157  }
158  while (($c=readdir($d))!==false) {
159  if (substr($c,0,1)!="." && is_dir($this->vhostroot."/".$c)) {
160  $this->subconcat($f,$this->vhostroot."/".$c);
161  }
162  }
163  closedir($d);
164  fclose($f);
165  rename($this->vhostroot."/vhosts_all.conf.new", $this->vhostroot."/vhosts_all.conf");
166  }
167 
168  private function subconcat($f,$root) {
169  // recursive cat :)
170  $d=opendir($root);
171  while (($c=readdir($d))!==false) {
172  if (substr($c,0,1)!=".") {
173  if (is_dir($root."/".$c)) {
174  $this->subconcat($f,$root."/".$c); // RECURSIVE CALL
175  }
176  if (is_file($root."/".$c)) {
177  fputs($f,file_get_contents($root."/".$c)."\n");
178  }
179  }
180  }
181  closedir($d);
182  }
183 
184 } // m_apache
185 
global $db
Definition: bootstrap.php:26
$msg
Definition: bootstrap.php:75
$root
Definition: bootstrap.php:20
$c
Definition: bootstrap.php:47
$d
Manages APACHE 2.4+ vhosts templates in AlternC 3.5+.
Definition: m_apache.php:26
$templatedir
Definition: m_apache.php:36
subconcat($f, $root)
Definition: m_apache.php:168
hook_updatedomains_web_del($subdomid)
launched for each FQDN for which we want to delete a vhost template
Definition: m_apache.php:108
hook_updatedomains_web_post()
launched at the very end of updatedomains
Definition: m_apache.php:124
concat()
Concatenate all files under $this->vhostroot into one (mindepth=2 though), this function is faster th...
Definition: m_apache.php:150
hook_updatedomains_web_pre()
Definition: m_apache.php:41
$shouldreload
Definition: m_apache.php:28
hook_updatedomains_web_add($subdomid)
Definition: m_apache.php:46
getuserpath($user=null)
get the home of the user
Definition: functions.php:329
if($delete!="") $cert