Marius Burkard
2016-05-04 c3189ce6c7301c3ec17878fd3918f31d0d3cb18a
commit | author | age
46c683 1 <?php
T 2
3 /*
cea1e5 4 Copyright (c) 2007 - 2012, Till Brehm, projektfarm Gmbh
46c683 5 All rights reserved.
T 6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 class apache2_plugin {
ac933e 32
46c683 33     var $plugin_name = 'apache2_plugin';
T 34     var $class_name = 'apache2_plugin';
ac933e 35
46c683 36     // private variables
T 37     var $action = '';
481c00 38     var $ssl_certificate_changed = false;
ac933e 39
46c683 40     //* This function is called during ispconfig installation to determine
T 41     //  if a symlink shall be created for this plugin.
42     function onInstall() {
43         global $conf;
ac933e 44
46c683 45         if($conf['services']['web'] == true) {
T 46             return true;
47         } else {
48             return false;
49         }
ac933e 50
46c683 51     }
ac933e 52
V 53
46c683 54     /*
T 55          This function is called when the plugin is loaded
56     */
ac933e 57
46c683 58     function onLoad() {
T 59         global $app;
ac933e 60
46c683 61         /*
T 62         Register for the events
63         */
b1a6a5 64         $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl');
MC 65         $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl');
66         $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl');
ac933e 67
b1a6a5 68         $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert');
MC 69         $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update');
70         $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete');
ac933e 71
b1a6a5 72         $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip');
MC 73         $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip');
74         $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip');
ac933e 75
b1a6a5 76         $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav');
MC 77         $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav');
78         $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav');
79
80         $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete');
81
82         $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user');
83         $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user');
84         $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user');
85
86         $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update');
87         $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete');
88
89         $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete');
90
91         $app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed');
46c683 92     }
b1a6a5 93
93292a 94     private function get_master_php_ini_content($web_data) {
MB 95         global $app, $conf;
96         
97         $app->uses('getconf');
98         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
99         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
100         
101         $php_ini_content = '';
102         $master_php_ini_path = '';
103         
104         if($web_data['php'] == 'mod') {
105             $master_php_ini_path = $web_config['php_ini_path_apache'];
106         } else {
107             // check for custom php
108             if($web_data['fastcgi_php_version'] != '') {
109                 $tmp = explode(':', $web_data['fastcgi_php_version']);
110                 if(isset($tmp[2])) {
111                     $tmppath = $tmp[2];
112                     if(substr($tmppath, -7) != 'php.ini') {
113                         if(substr($tmppath, -1) != '/') $tmppath .= '/';
114                         $tmppath .= 'php.ini';
115                     }
116                     if(file_exists($tmppath)) {
117                         $master_php_ini_path = $tmppath;
118                     }
119                     unset($tmppath);
120                 }
121                 unset($tmp);
122             }
123             
124             if(!$master_php_ini_path) {
125                 if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
126                     $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
127                 } elseif($web_data['php'] == 'php-fpm' && file_exists($web_config['php_fpm_ini_path'])) {
128                     $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
129                 } else {
130                     $master_php_ini_path = $web_config['php_ini_path_cgi'];
131                 }
132             }
133         }
134         if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) {
135             $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
136         }
137         
138         return $php_ini_content;
139     }
b1a6a5 140
MC 141     // Handle php.ini changes
142     function php_ini_changed($event_name, $data) {
143         global $app, $conf;
144
145         $app->uses('getconf');
bd68aa 146         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
MC 147         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
b1a6a5 148
MC 149         /* $data contains an array with these keys:
bd68aa 150          * file -> full path of changed php_ini
c59632 151          * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm, hhvm or '' for all except 'mod')
bd68aa 152          * php_version -> php ini path that changed (additional php versions)
MC 153          */
b1a6a5 154
2af58c 155         $param = '';
b1a6a5 156         $qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''";
MC 157         if($data['mode'] == 'mod') {
158             $qrystr .= " AND php = 'mod'";
159         } elseif($data['mode'] == 'fast-cgi') {
160             $qrystr .= " AND php = 'fast-cgi'";
161             if($data['php_version']) {
2af58c 162                 $qrystr .= " AND fastcgi_php_version LIKE ?";
MC 163                 $param = '%:' . $data['php_version'];
b1a6a5 164             }
MC 165         } elseif($data['mode'] == 'php-fpm') {
166             $qrystr .= " AND php = 'php-fpm'";
c59632 167             if($data['php_version']) {
2af58c 168                 $qrystr .= " AND fastcgi_php_version LIKE ?";
MC 169                 $param = '%:' . $data['php_version'] . ':%';
c59632 170             }
MC 171         } elseif($data['mode'] == 'hhvm') {
172             $qrystr .= " AND php = 'hhvm'";
b1a6a5 173             if($data['php_version']) {
2af58c 174                 $qrystr .= " AND fastcgi_php_version LIKE ?";
MC 175                 $param = '%:' . $data['php_version'] . ':%';
b1a6a5 176             }
MC 177         } else {
178             $qrystr .= " AND php != 'mod' AND php != 'fast-cgi'";
179         }
ac933e 180
bd68aa 181
b1a6a5 182         //** Get all the webs
2af58c 183         $web_domains = $app->db->queryAllRecords($qrystr, $param);
b1a6a5 184         foreach($web_domains as $web_data) {
MC 185             $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user'];
186             $web_folder = 'web';
511ba5 187             if($web_data['type'] == 'vhostsubdomain' || $web_data['type'] == 'vhostalias') {
b1a6a5 188                 $web_folder = $web_data['web_folder'];
MC 189                 $custom_php_ini_dir .= '_' . $web_folder;
190             }
191             if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');
93292a 192             
b1a6a5 193             if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir);
93292a 194             
MB 195             $php_ini_content = $this->get_master_php_ini_content($web_data);
b41803 196             
MC 197             if(intval($web_data['directive_snippets_id']) > 0){
d22277 198                 $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id']));
b41803 199                 if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
MC 200                     $required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
201                     if(is_array($required_php_snippets) && !empty($required_php_snippets)){
202                         foreach($required_php_snippets as $required_php_snippet){
203                             $required_php_snippet = intval($required_php_snippet);
204                             if($required_php_snippet > 0){
205                                 $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
206                                 $php_snippet['snippet'] = trim($php_snippet['snippet']);
207                                 if($php_snippet['snippet'] != ''){
208                                     $web_data['custom_php_ini'] .= "\n".$php_snippet['snippet'];
209                                 }
210                             }
211                         }
212                     }
213                 }
214             }
215         
b1a6a5 216             $php_ini_content .= str_replace("\r", '', trim($web_data['custom_php_ini']));
MC 217             $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content);
218             $app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').', LOGLEVEL_DEBUG);
219         }
220
221         if(count($web_domains) > 0) {
222             //* We do not check the apache config here - we only changed the php.ini
223             //* Check if this is a chrooted setup
224             if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
225                 $apache_chrooted = true;
226                 $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
227             } else {
228                 $apache_chrooted = false;
229             }
230
231             $app->log('Info: rewrote all php.ini and reloading apache now.', LOGLEVEL_DEBUG);
232             if($apache_chrooted) {
233                 $app->services->restartServiceDelayed('httpd', 'restart');
234             } else {
235                 // request a httpd reload when all records have been processed
236                 $app->services->restartServiceDelayed('httpd', 'reload');
237             }
238         } else {
239             $app->log('Info: No webs affected by php.ini change.', LOGLEVEL_DEBUG);
240         }
241     }
242
46c683 243     // Handle the creation of SSL certificates
b1a6a5 244     function ssl($event_name, $data) {
46c683 245         global $app, $conf;
b1a6a5 246
c77103 247         $app->uses('system');
1a2310 248
L 249         // load the server configuration options
250         $app->uses('getconf');
251         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
252         if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf'))
b1a6a5 253             $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR);
MC 254
1ca823 255         //* Only vhosts can have a ssl cert
511ba5 256         if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return;
ac933e 257
c77103 258         // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
T 259         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
b1a6a5 260
fb3339 261         $ssl_dir = $data['new']['document_root'].'/ssl';
J 262         $domain = $data['new']['ssl_domain'];
263         $key_file = $ssl_dir.'/'.$domain.'.key.org';
264         $key_file2 = $ssl_dir.'/'.$domain.'.key';
265         $csr_file = $ssl_dir.'/'.$domain.'.csr';
266         $crt_file = $ssl_dir.'/'.$domain.'.crt';
ac933e 267
4bd960 268         //* Create a SSL Certificate, but only if this is not a mirror server.
T 269         if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) {
b1a6a5 270
481c00 271             $this->ssl_certificate_changed = true;
b1a6a5 272
e94a9f 273             //* Rename files if they exist
43b345 274             if(file_exists($key_file)){
b1a6a5 275                 $app->system->rename($key_file, $key_file.'.bak');
MC 276                 $app->system->chmod($key_file.'.bak', 0400);
43b345 277             }
T 278             if(file_exists($key_file2)){
b1a6a5 279                 $app->system->rename($key_file2, $key_file2.'.bak');
MC 280                 $app->system->chmod($key_file2.'.bak', 0400);
43b345 281             }
b1a6a5 282             if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak');
MC 283             if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak');
284
fb3339 285             $rand_file = $ssl_dir.'/random_file';
b1a6a5 286             $rand_data = md5(uniqid(microtime(), 1));
ac933e 287             for($i=0; $i<1000; $i++) {
b1a6a5 288                 $rand_data .= md5(uniqid(microtime(), 1));
MC 289                 $rand_data .= md5(uniqid(microtime(), 1));
290                 $rand_data .= md5(uniqid(microtime(), 1));
291                 $rand_data .= md5(uniqid(microtime(), 1));
ac933e 292             }
c77103 293             $app->system->file_put_contents($rand_file, $rand_data);
46c683 294
b1a6a5 295             $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15);
ac933e 296
46c683 297             $ssl_cnf = "        RANDFILE               = $rand_file
T 298
299         [ req ]
6d80f5 300         default_bits           = 2048
6068b7 301         default_md             = sha256
46c683 302         default_keyfile        = keyfile.pem
T 303         distinguished_name     = req_distinguished_name
304         attributes             = req_attributes
305         prompt                 = no
306         output_password        = $ssl_password
307
308         [ req_distinguished_name ]
e94a9f 309         C                      = ".trim($data['new']['ssl_country'])."
243697 310         " . (trim($data['new']['ssl_state']) == '' ? '' : "ST                     = ".trim($data['new']['ssl_state'])) . "
MB 311         " . (trim($data['new']['ssl_locality']) == '' ? '' : "L                      = ".trim($data['new']['ssl_locality']))."
312         " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O                      = ".trim($data['new']['ssl_organisation']))."
313         " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU                     = ".trim($data['new']['ssl_organisation_unit']))."
46c683 314         CN                     = $domain
T 315         emailAddress           = webmaster@".$data['new']['domain']."
316
317         [ req_attributes ]
5a4285 318         ";//challengePassword              = A challenge password";
ac933e 319
fb3339 320             $ssl_cnf_file = $ssl_dir.'/openssl.conf';
b1a6a5 321             $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf);
ac933e 322
46c683 323             $rand_file = escapeshellcmd($rand_file);
T 324             $key_file = escapeshellcmd($key_file);
8c82ef 325             $openssl_cmd_key_file = $key_file;
992797 326             if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate
46c683 327             $key_file2 = escapeshellcmd($key_file2);
8c82ef 328             $openssl_cmd_key_file2 = $key_file2;
992797 329             if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate
46c683 330             $ssl_days = 3650;
T 331             $csr_file = escapeshellcmd($csr_file);
8c82ef 332             $openssl_cmd_csr_file = $csr_file;
992797 333             if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate
46c683 334             $config_file = escapeshellcmd($ssl_cnf_file);
T 335             $crt_file = escapeshellcmd($crt_file);
8c82ef 336             $openssl_cmd_crt_file = $crt_file;
992797 337             if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate
46c683 338
c77103 339             if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) {
b1a6a5 340
8c82ef 341                 exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file 2048");
6068b7 342                 exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file -out $openssl_cmd_csr_file -days $ssl_days -config $config_file");
8c82ef 343                 exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file -out $openssl_cmd_key_file2");
1a2310 344
L 345                 if(file_exists($web_config['CA_path'].'/openssl.cnf'))
5c4d55 346                 {
8c82ef 347                     exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file");
b1a6a5 348                     $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
8c82ef 349                     if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed.  openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR);
1a2310 350                 };
723662 351                 if (@filesize($crt_file)==0 || !file_exists($crt_file)){
8c82ef 352                     exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file ");
b1a6a5 353                     $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
5c4d55 354                 };
b1a6a5 355
ac933e 356             }
46c683 357
b1a6a5 358             $app->system->chmod($key_file, 0400);
MC 359             $app->system->chmod($key_file2, 0400);
c77103 360             @$app->system->unlink($config_file);
T 361             @$app->system->unlink($rand_file);
2af58c 362             $ssl_request = $app->system->file_get_contents($csr_file);
MC 363             $ssl_cert = $app->system->file_get_contents($crt_file);
364             $ssl_key2 = $app->system->file_get_contents($key_file2);
d1086f 365             /* Update the DB of the (local) Server */
2af58c 366             $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key2, $data['new']['domain']);
MC 367             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
d1086f 368             /* Update also the master-DB of the Server-Farm */
2af58c 369             $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key2, $data['new']['domain']);
MC 370             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
46c683 371         }
bff982 372         
TB 373         //* Check that the SSL key is not password protected
374         if($data["new"]["ssl_action"] == 'save') {
375             if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) {
376                 $data["new"]["ssl_action"] = '';
377             
378                 $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN);
379                 $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.');
380             
381                 /* Update the DB of the (local) Server */
382                 $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
383
384                 /* Update also the master-DB of the Server-Farm */
385                 $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
386             }
387         }
ac933e 388
46c683 389         //* Save a SSL certificate to disk
9f56bd 390         if($data["new"]["ssl_action"] == 'save') {
481c00 391             $this->ssl_certificate_changed = true;
9f56bd 392             $ssl_dir = $data["new"]["document_root"]."/ssl";
edf806 393             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
481c00 394             $key_file = $ssl_dir.'/'.$domain.'.key.org';
0d20af 395             $key_file2 = $ssl_dir.'/'.$domain.'.key';
9f56bd 396             $csr_file = $ssl_dir.'/'.$domain.".csr";
T 397             $crt_file = $ssl_dir.'/'.$domain.".crt";
398             $bundle_file = $ssl_dir.'/'.$domain.".bundle";
b1a6a5 399
481c00 400             //* Backup files
43b345 401             if(file_exists($key_file)){
b1a6a5 402                 $app->system->copy($key_file, $key_file.'~');
MC 403                 $app->system->chmod($key_file.'~', 0400);
43b345 404             }
T 405             if(file_exists($key_file2)){
b1a6a5 406                 $app->system->copy($key_file2, $key_file2.'~');
MC 407                 $app->system->chmod($key_file2.'~', 0400);
43b345 408             }
b1a6a5 409             if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~');
MC 410             if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~');
411             if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~');
412
481c00 413             //* Write new ssl files
b1a6a5 414             if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]);
f78f1e 415             if(version_compare($app->system->getapacheversion(true), '2.4.8', '>=')) {
MC 416                 $tmp_data = '';
417                 if(trim($data["new"]["ssl_cert"]) != '') $tmp_data .= $data["new"]["ssl_cert"] . "\n";
418                 if(trim($data["new"]["ssl_bundle"]) != '') $tmp_data .= $data["new"]["ssl_bundle"];
419                 if(trim($tmp_data) != '') $app->system->file_put_contents($crt_file, $tmp_data);
420             } else {
421                 if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]);
422                 if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]);
423             }
b1a6a5 424
72695f 425             //* Write the key file, if field is empty then import the key into the db
T 426             if(trim($data["new"]["ssl_key"]) != '') {
b1a6a5 427                 $app->system->file_put_contents($key_file2, $data["new"]["ssl_key"]);
MC 428                 $app->system->chmod($key_file2, 0400);
72695f 429             } else {
2af58c 430                 $ssl_key2 = $app->system->file_get_contents($key_file2);
72695f 431                 /* Update the DB of the (local) Server */
2af58c 432                 $app->db->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key2, $data['new']['domain']);
72695f 433                 /* Update also the master-DB of the Server-Farm */
2af58c 434                 $app->dbmaster->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key2, $data['new']['domain']);
72695f 435             }
b1a6a5 436
d1086f 437             /* Update the DB of the (local) Server */
2af58c 438             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
b1a6a5 439
d1086f 440             /* Update also the master-DB of the Server-Farm */
2af58c 441             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
b1a6a5 442             $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
46c683 443         }
ac933e 444
46c683 445         //* Delete a SSL certificate
fb3339 446         if($data['new']['ssl_action'] == 'del') {
J 447             $ssl_dir = $data['new']['document_root'].'/ssl';
edf806 448             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
fb3339 449             $csr_file = $ssl_dir.'/'.$domain.'.csr';
J 450             $crt_file = $ssl_dir.'/'.$domain.'.crt';
451             $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
c77103 452             if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf'))
b1a6a5 453             {
8c82ef 454                 exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file));
b1a6a5 455                 $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
MC 456             };
c77103 457             $app->system->unlink($csr_file);
T 458             $app->system->unlink($crt_file);
459             $app->system->unlink($bundle_file);
d1086f 460             /* Update the DB of the (local) Server */
2af58c 461             $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ?", $data['new']['domain']);
MC 462             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
d1086f 463             /* Update also the master-DB of the Server-Farm */
2af58c 464             $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ?", $data['new']['domain']);
MC 465             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
b1a6a5 466             $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
46c683 467         }
ac933e 468
46c683 469     }
ac933e 470
V 471
b1a6a5 472     function insert($event_name, $data) {
46c683 473         global $app, $conf;
ac933e 474
46c683 475         $this->action = 'insert';
T 476         // just run the update function
b1a6a5 477         $this->update($event_name, $data);
ac933e 478
V 479
46c683 480     }
ac933e 481
V 482
b1a6a5 483     function update($event_name, $data) {
46c683 484         global $app, $conf;
ac933e 485
46c683 486         if($this->action != 'insert') $this->action = 'update';
ac933e 487
511ba5 488         if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) {
ac933e 489
fb3339 490             $old_parent_domain_id = intval($data['old']['parent_domain_id']);
J 491             $new_parent_domain_id = intval($data['new']['parent_domain_id']);
ac933e 492
1ca823 493             // If the parent_domain_id has been changed, we will have to update the old site as well.
fb3339 494             if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) {
2af58c 495                 $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y');
fb3339 496                 $data['new'] = $tmp;
J 497                 $data['old'] = $tmp;
46c683 498                 $this->action = 'update';
b1a6a5 499                 $this->update($event_name, $data);
46c683 500             }
ac933e 501
46c683 502             // This is not a vhost, so we need to update the parent record instead.
5d0363 503             $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y');
fb3339 504             $data['new'] = $tmp;
J 505             $data['old'] = $tmp;
46c683 506             $this->action = 'update';
T 507         }
ac933e 508
46c683 509         // load the server configuration options
fb3339 510         $app->uses('getconf');
J 511         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 512
2bbc4c 513         //* Check if this is a chrooted setup
155cc0 514         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 515             $apache_chrooted = true;
b1a6a5 516             $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
2bbc4c 517         } else {
T 518             $apache_chrooted = false;
519         }
ac933e 520
fb3339 521         if($data['new']['document_root'] == '') {
511ba5 522             if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN);
46c683 523             return 0;
T 524         }
15687e 525         if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false
TB 526             || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) {
527             $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN);
46c683 528             return 0;
T 529         }
e94a9f 530         if(trim($data['new']['domain']) == '') {
b1a6a5 531             $app->log('domain is empty', LOGLEVEL_WARN);
e94a9f 532             return 0;
T 533         }
b1a6a5 534
MC 535         $web_folder = 'web';
536         $log_folder = 'log';
79d955 537         $old_web_folder = 'web';
MC 538         $old_log_folder = 'log';
511ba5 539         if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') {
79d955 540             // new one
2af58c 541             $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
b1a6a5 542             $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']);
MC 543             if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id'];
544             $web_folder = $data['new']['web_folder'];
545             $log_folder .= '/' . $subdomain_host;
546             unset($tmp);
79d955 547             
MC 548             if(isset($data['old']['parent_domain_id'])) {
549                 // old one
2af58c 550                 $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
79d955 551                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
MC 552                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
553                 $old_web_folder = $data['old']['web_folder'];
554                 $old_log_folder .= '/' . $subdomain_host;
555                 unset($tmp);
556             }
b1a6a5 557         }
6fb93d 558
dba68f 559         // Create group and user, if not exist
T 560         $app->uses('system');
b1a6a5 561
8cf78b 562         if($web_config['connect_userid_to_webid'] == 'y') {
T 563             //* Calculate the uid and gid
564             $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']);
565             $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']);
566             $fixed_uid_param = '--uid '.$fixed_uid_gid;
567             $fixed_gid_param = '--gid '.$fixed_uid_gid;
b1a6a5 568
8cf78b 569             //* Check if a ispconfigend user and group exists and create them
T 570             if(!$app->system->is_group('ispconfigend')) {
571                 exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
572             }
573             if(!$app->system->is_user('ispconfigend')) {
574                 exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
575             }
576         } else {
577             $fixed_uid_param = '';
578             $fixed_gid_param = '';
579         }
dba68f 580
T 581         $groupname = escapeshellcmd($data['new']['system_group']);
582         if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
8cf78b 583             exec('groupadd '.$fixed_gid_param.' '.$groupname);
dba68f 584             if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname);
b1a6a5 585             $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG);
dba68f 586         }
T 587
588         $username = escapeshellcmd($data['new']['system_user']);
589         if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) {
8cf78b 590             if($web_config['add_web_users_to_sshusers_group'] == 'y') {
T 591                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
592                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
593             } else {
594                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
595                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
596             }
b1a6a5 597             $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG);
dba68f 598         }
ac933e 599
46c683 600         //* If the client of the site has been changed, we have a change of the document root
fb3339 601         if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
ac933e 602
46c683 603             //* Get the old client ID
2af58c 604             $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']);
fb3339 605             $old_client_id = intval($old_client['client_id']);
46c683 606             unset($old_client);
ac933e 607
46c683 608             //* Remove the old symlinks
b1a6a5 609             $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 610             if(is_array($tmp_symlinks_array)) {
T 611                 foreach($tmp_symlinks_array as $tmp_symlink) {
b1a6a5 612                     $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink);
MC 613                     $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
46c683 614                     // Remove trailing slash
T 615                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
616                     // create the symlinks, if not exist
436975 617                     if(is_link($tmp_symlink)) {
fb3339 618                         exec('rm -f '.escapeshellcmd($tmp_symlink));
b1a6a5 619                         $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 620                     }
T 621                 }
622             }
b1a6a5 623
4b9329 624             //* Remove protection of old folders
b1a6a5 625             $app->system->web_folder_protection($data['old']['document_root'], false);
ac933e 626
511ba5 627             if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") {
b1a6a5 628                 //* Move the site data
MC 629                 $tmp_docroot = explode('/', $data['new']['document_root']);
630                 unset($tmp_docroot[count($tmp_docroot)-1]);
631                 $new_dir = implode('/', $tmp_docroot);
ac933e 632
b1a6a5 633                 $tmp_docroot = explode('/', $data['old']['document_root']);
MC 634                 unset($tmp_docroot[count($tmp_docroot)-1]);
635                 $old_dir = implode('/', $tmp_docroot);
ac933e 636
b1a6a5 637                 //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path
MC 638                 if(@is_dir($data['new']['document_root'])) {
639                     $app->system->web_folder_protection($data['new']['document_root'], false);
640                     $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'));
641                     $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG);
642                 }
3fb802 643                 
TB 644                 //* Unmount the old log directory bfore we move the log dir
a9b325 645                 //exec('fuser -km '.escapeshellcmd($old_dir.'/log'));
c8679f 646                 exec('umount '.escapeshellcmd($data['old']['document_root'].'/log'));
ac933e 647
b1a6a5 648                 //* Create new base directory, if it does not exist yet
MC 649                 if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir);
650                 $app->system->web_folder_protection($data['old']['document_root'], false);
651                 exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir));
652                 //$app->system->rename($data['old']['document_root'],$new_dir);
653                 $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG);
0930f5 654
b1a6a5 655                 // Handle the change in php_open_basedir
MC 656                 $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']);
657
658                 //* Change the owner of the website files to the new website owner
659                 exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir);
660
661                 //* Change the home directory and group of the website user
662                 $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod';
663                 $command .= ' --home '.escapeshellcmd($data['new']['document_root']);
664                 $command .= ' --gid '.escapeshellcmd($data['new']['system_group']);
665                 $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
666                 exec($command);
667             }
668
fb3339 669             if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
b1a6a5 670
10b4c8 671             //* Change the log mount
074a57 672             /*
79d955 673             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
b1a6a5 674             $app->system->removeLine('/etc/fstab', $fstab_line);
79d955 675             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
ff5b86 676             $app->system->removeLine('/etc/fstab', $fstab_line);
074a57 677             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
TB 678             $app->system->removeLine('/etc/fstab', $fstab_line);
679             */
680             
681             $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
682             
683             if($web_config['network_filesystem'] == 'y') {
684                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
685                 $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
686             } else {
687                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
688                 $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
689             }
3fb802 690             
TB 691             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
074a57 692             
46c683 693         }
ac933e 694
46c683 695         //print_r($data);
ac933e 696
fb3339 697         // Check if the directories are there and create them if necessary.
b1a6a5 698         $app->system->web_folder_protection($data['new']['document_root'], false);
MC 699
6fb93d 700         if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder);
M 701         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error');
f0dfa9 702         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/stats');
6fb93d 703         //if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder);
c77103 704         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
T 705         if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
706         if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp');
707         if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav');
b1a6a5 708
d87f76 709         //* Create the new private directory
T 710         if(!is_dir($data['new']['document_root'].'/private')) {
711             $app->system->mkdirpath($data['new']['document_root'].'/private');
b1a6a5 712             $app->system->chmod($data['new']['document_root'].'/private', 0710);
MC 713             $app->system->chown($data['new']['document_root'].'/private', $username);
714             $app->system->chgrp($data['new']['document_root'].'/private', $groupname);
d87f76 715         }
b1a6a5 716
MC 717
46c683 718         // Remove the symlink for the site, if site is renamed
fb3339 719         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
J 720             if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
79d955 721             if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder);
b1a6a5 722
10b4c8 723             //* remove old log mount
79d955 724             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
b1a6a5 725             $app->system->removeLine('/etc/fstab', $fstab_line);
MC 726
10b4c8 727             //* Unmount log directory
a9b325 728             //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
79d955 729             exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
46c683 730         }
b1a6a5 731
d5a517 732         //* Create the log dir if nescessary and mount it
10b4c8 733         if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) {
6fb93d 734             if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder);
10b4c8 735             if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']);
c3bf39 736             $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder);
b1a6a5 737             $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root');
MC 738             $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root');
739             $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
6fb93d 740             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
d5a517 741             //* add mountpoint to fstab
c8679f 742             $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait';
FS 743             $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev    0 0':'    0 0';
b1a6a5 744             $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
d5a517 745         }
b1a6a5 746
MC 747         $app->system->web_folder_protection($data['new']['document_root'], true);
ac933e 748
46c683 749         // Get the client ID
2af58c 750         $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']);
fb3339 751         $client_id = intval($client['client_id']);
46c683 752         unset($client);
ac933e 753
46c683 754         // Remove old symlinks, if site is renamed
fb3339 755         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
b1a6a5 756             $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 757             if(is_array($tmp_symlinks_array)) {
T 758                 foreach($tmp_symlinks_array as $tmp_symlink) {
b1a6a5 759                     $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
MC 760                     $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
46c683 761                     // Remove trailing slash
T 762                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
763                     // remove the symlinks, if not exist
764                     if(is_link($tmp_symlink)) {
fb3339 765                         exec('rm -f '.escapeshellcmd($tmp_symlink));
b1a6a5 766                         $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 767                     }
T 768                 }
769             }
770         }
ac933e 771
46c683 772         // Create the symlinks for the sites
b1a6a5 773         $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 774         if(is_array($tmp_symlinks_array)) {
T 775             foreach($tmp_symlinks_array as $tmp_symlink) {
b1a6a5 776                 $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
MC 777                 $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink);
46c683 778                 // Remove trailing slash
T 779                 if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
780                 //* Remove symlink if target folder has been changed.
fb3339 781                 if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) {
c77103 782                     $app->system->unlink($tmp_symlink);
46c683 783                 }
T 784                 // create the symlinks, if not exist
785                 if(!is_link($tmp_symlink)) {
b1a6a5 786                     //     exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
552178 787                     if ($web_config["website_symlinks_rel"] == 'y') {
M 788                         $this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink));
789                     } else {
790                         exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
791                     }
792
b1a6a5 793                     $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 794                 }
T 795             }
796         }
ac933e 797
V 798
3e41e8 799
b1a6a5 800         // Install the Standard or Custom Error, Index and other related files
MC 801         // /usr/local/ispconfig/server/conf is for the standard files
802         // /usr/local/ispconfig/server/conf-custom is for the custom files
803         // setting a local var here
804
805         // normally $conf['templates'] = "/usr/local/ispconfig/server/conf";
511ba5 806         if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) {
b1a6a5 807
MC 808             // Copy the error pages
fb3339 809             if($data['new']['errordocs']) {
6fb93d 810                 $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
b1a6a5 811                 if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 812                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 813                 }
T 814                 else {
4ffb51 815                     if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
F 816                         exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
46c683 817                     }
T 818                     else {
b1a6a5 819                         exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 820                     }
T 821                 }
fb3339 822                 exec('chmod -R a+r '.$error_page_path);
46c683 823             }
T 824
b1a6a5 825             if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) {
f0dfa9 826                 if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
b1a6a5 827
MC 828                 if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) {
f0dfa9 829                     if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
b1a6a5 830                 }
MC 831                 if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) {
f0dfa9 832                     if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
b1a6a5 833                 }
MC 834                 if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) {
f0dfa9 835                     if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
b1a6a5 836                 }
f0dfa9 837             } else {
4ffb51 838                 if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) {
f0dfa9 839                     if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
MC 840                 } else {
841                     if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
842                     if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){
843                         if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
844                     }
845                     if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){
846                         if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
847                     }
848                     if(is_file($conf['rootpath'] . '/conf/index/.htaccess')){
849                         if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
850                     }
46c683 851                 }
T 852             }
6fb93d 853             exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
ac933e 854
V 855             //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
511ba5 856         } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
b1a6a5 857
6fb93d 858             $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
b1a6a5 859             if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 860                 exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 861             }
T 862             else {
4ffb51 863                 if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
F 864                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
46c683 865                 }
T 866                 else {
b1a6a5 867                     exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 868                 }
T 869             }
fb3339 870             exec('chmod -R a+r '.$error_page_path);
5d5d88 871             exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
46c683 872         }  // end copy error docs
ac933e 873
511ba5 874         // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias
cc6568 875         if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') {
fb3339 876             if($data['new']['hd_quota'] > 0) {
J 877                 $blocks_soft = $data['new']['hd_quota'] * 1024;
ac933e 878                 $blocks_hard = $blocks_soft + 1024;
e14c6e 879                 $mb_hard = $mb_soft + 1;
ac933e 880             } else {
e14c6e 881                 $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0;
ac933e 882             }
e14c6e 883             
D 884           // get the primitive folder for document_root and the filesystem, will need it later.
885           $df_output=exec("df -T $document_root|awk 'END{print \$2,\$NF}'");
886           $file_system = explode(" ", $df_output)[0];
887           $primitive_root = explode(" ", $df_output)[1];
888
e4393f 889           if ( in_array($file_system , array('ext2','ext3','ext4'), true) ) {
e14c6e 890             exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null');
D 891             exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
892           } elseif ($file_system == 'xfs') {
893
894             exec("xfs_quota -x -c 'limit -g bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " $username' $primitive_root");
895
896             // xfs only supports timers globally, not per user.
897             exec("xfs_quota -x -c 'timer -bir -i 604800'");
898
899             unset($project_uid, $username_position, $xfs_projects);
900             unset($primitive_root, $df_output, $mb_hard, $mb_soft);
901           }
46c683 902         }
ac933e 903
1ca823 904         if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
46c683 905             // Chown and chmod the directories below the document root
6fb93d 906             $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 907             // The document root itself has to be owned by root in normal level and by the web owner in security level 20
T 908             if($web_config['security_level'] == 20) {
6fb93d 909                 $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 910             } else {
6fb93d 911                 $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 912             }
46c683 913         }
b1a6a5 914
615a0a 915         //* add the Apache user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update
T 916         if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
ac933e 917
8db8f3 918         //* If the security level is set to high
8cf78b 919         if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
b1a6a5 920
MC 921             $app->system->web_folder_protection($data['new']['document_root'], false);
922
d87f76 923             //* Check if we have the new private folder and create it if nescessary
T 924             if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private');
b1a6a5 925
edf806 926             if($web_config['security_level'] == 20) {
b1a6a5 927
MC 928                 $app->system->chmod($data['new']['document_root'], 0755);
7c37ed 929                 $app->system->chmod($data['new']['document_root'].'/web', 0711);
b1a6a5 930                 $app->system->chmod($data['new']['document_root'].'/webdav', 0710);
MC 931                 $app->system->chmod($data['new']['document_root'].'/private', 0710);
932                 $app->system->chmod($data['new']['document_root'].'/ssl', 0755);
ac933e 933
edf806 934                 // make tmp directory writable for Apache and the website users
5aedfd 935                 $app->system->chmod($data['new']['document_root'].'/tmp', 0770);
b1a6a5 936
cea1e5 937                 // Set Log directory to 755 to make the logs accessible by the FTP user
418b41 938                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
b1a6a5 939                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
c77103 940                 }
b1a6a5 941
8cf78b 942                 if($web_config['add_web_users_to_sshusers_group'] == 'y') {
T 943                     $command = 'usermod';
944                     $command .= ' --groups sshusers';
526b99 945                     $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
8cf78b 946                     $this->_exec($command);
T 947                 }
ac933e 948
edf806 949                 //* if we have a chrooted Apache environment
T 950                 if($apache_chrooted) {
951                     $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
ac933e 952
edf806 953                     //* add the apache user to the client group in the chroot environment
T 954                     $tmp_groupfile = $app->system->server_conf['group_datei'];
955                     $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group';
956                     $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
957                     $app->system->server_conf['group_datei'] = $tmp_groupfile;
958                     unset($tmp_groupfile);
959                 }
b1a6a5 960
8cf78b 961                 //* Chown all default directories
b1a6a5 962                 $app->system->chown($data['new']['document_root'], 'root');
MC 963                 $app->system->chgrp($data['new']['document_root'], 'root');
964                 $app->system->chown($data['new']['document_root'].'/cgi-bin', $username);
965                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname);
418b41 966                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
b1a6a5 967                     $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false);
MC 968                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false);
c77103 969                 }
b1a6a5 970                 $app->system->chown($data['new']['document_root'].'/ssl', 'root');
MC 971                 $app->system->chgrp($data['new']['document_root'].'/ssl', 'root');
972                 $app->system->chown($data['new']['document_root'].'/tmp', $username);
973                 $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname);
974                 $app->system->chown($data['new']['document_root'].'/web', $username);
975                 $app->system->chgrp($data['new']['document_root'].'/web', $groupname);
976                 $app->system->chown($data['new']['document_root'].'/web/error', $username);
977                 $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname);
978                 $app->system->chown($data['new']['document_root'].'/web/stats', $username);
979                 $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
980                 $app->system->chown($data['new']['document_root'].'/webdav', $username);
981                 $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname);
982                 $app->system->chown($data['new']['document_root'].'/private', $username);
983                 $app->system->chgrp($data['new']['document_root'].'/private', $groupname);
ac933e 984
edf806 985                 // If the security Level is set to medium
T 986             } else {
987
b1a6a5 988                 $app->system->chmod($data['new']['document_root'], 0755);
MC 989                 $app->system->chmod($data['new']['document_root'].'/web', 0755);
990                 $app->system->chmod($data['new']['document_root'].'/webdav', 0755);
991                 $app->system->chmod($data['new']['document_root'].'/ssl', 0755);
992                 $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755);
993
edf806 994                 // make temp directory writable for Apache and the website users
5aedfd 995                 $app->system->chmod($data['new']['document_root'].'/tmp', 0770);
b1a6a5 996
6fb93d 997                 // Set Log directory to 755 to make the logs accessible by the FTP user
418b41 998                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
b1a6a5 999                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
6fb93d 1000                 }
b1a6a5 1001
MC 1002                 $app->system->chown($data['new']['document_root'], 'root');
1003                 $app->system->chgrp($data['new']['document_root'], 'root');
1004                 $app->system->chown($data['new']['document_root'].'/cgi-bin', $username);
1005                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname);
418b41 1006                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
b1a6a5 1007                     $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false);
MC 1008                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false);
c77103 1009                 }
b1a6a5 1010
MC 1011                 $app->system->chown($data['new']['document_root'].'/ssl', 'root');
1012                 $app->system->chgrp($data['new']['document_root'].'/ssl', 'root');
1013                 $app->system->chown($data['new']['document_root'].'/tmp', $username);
1014                 $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname);
1015                 $app->system->chown($data['new']['document_root'].'/web', $username);
1016                 $app->system->chgrp($data['new']['document_root'].'/web', $groupname);
1017                 $app->system->chown($data['new']['document_root'].'/web/error', $username);
1018                 $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname);
1019                 $app->system->chown($data['new']['document_root'].'/web/stats', $username);
1020                 $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
1021                 $app->system->chown($data['new']['document_root'].'/webdav', $username);
1022                 $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname);
8db8f3 1023             }
511ba5 1024         } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) &&
DM 1025                  (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) {
1026
6fb93d 1027             if($web_config['security_level'] == 20) {
b1a6a5 1028                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710);
MC 1029                 $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
1030                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname);
1031                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username);
1032                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname);
1033                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username);
1034                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname);
1035             } else {
1036                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755);
1037                 $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
1038                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname);
1039                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username);
1040                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname);
1041                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username);
1042                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname);
1043             }
1044         }
1045
4b9329 1046         //* Protect web folders
b1a6a5 1047         $app->system->web_folder_protection($data['new']['document_root'], true);
ac933e 1048
6fb93d 1049         if($data['new']['type'] == 'vhost') {
b1a6a5 1050             // Change the ownership of the error log to the root user
MC 1051             if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log'));
1052             $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
1053             $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
1054         }
ac933e 1055
26c0fc 1056         //* Write the custom php.ini file, if custom_php_ini fieled is not empty
fb3339 1057         $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
511ba5 1058         if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder;
c77103 1059         if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');
b1a6a5 1060
26c0fc 1061         //* add open_basedir restriction to custom php.ini content, required for suphp only
b1a6a5 1062         if(!stristr($data['new']['custom_php_ini'], 'open_basedir') && $data['new']['php'] == 'suphp') {
26c0fc 1063             $data['new']['custom_php_ini'] .= "\nopen_basedir = '".$data['new']['php_open_basedir']."'\n";
T 1064         }
b1a6a5 1065
cc6568 1066         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
b1a6a5 1067
cc6568 1068         if(trim($data['new']['fastcgi_php_version']) != ''){
H 1069             list($custom_fastcgi_php_name, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
1070             if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir);
b1a6a5 1071             if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1);
cc6568 1072         }
H 1073
26c0fc 1074         //* Create custom php.ini
fb3339 1075         if(trim($data['new']['custom_php_ini']) != '') {
7fddfe 1076             $has_custom_php_ini = true;
3f478f 1077             if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir);
93292a 1078             
MB 1079             $php_ini_content = $this->get_master_php_ini_content($data['new']);
b1a6a5 1080             $php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini']));
b41803 1081             
MC 1082             if(intval($data['new']['directive_snippets_id']) > 0){
d22277 1083                 $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
b41803 1084                 if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
MC 1085                     $required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
1086                     if(is_array($required_php_snippets) && !empty($required_php_snippets)){
1087                         foreach($required_php_snippets as $required_php_snippet){
1088                             $required_php_snippet = intval($required_php_snippet);
1089                             if($required_php_snippet > 0){
1090                                 $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
1091                                 $php_snippet['snippet'] = trim($php_snippet['snippet']);
1092                                 if($php_snippet['snippet'] != ''){
1093                                     $php_ini_content .= "\n".$php_snippet['snippet'];
1094                                 }
1095                             }
1096                         }
34c940 1097
MB 1098                         foreach($sub_prefixes as $s) {
1099                             $temp_domains[] = $s . $aliasdomain['domain'];
1100                         }
b41803 1101                     }
MC 1102                 }
1103             }
1104         
b1a6a5 1105             $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content);
7fddfe 1106         } else {
T 1107             $has_custom_php_ini = false;
c77103 1108             if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini');
7fddfe 1109         }
T 1110
1111
1112         //* Create the vhost config file
46c683 1113         $app->load('tpl');
ac933e 1114
46c683 1115         $tpl = new tpl();
fb3339 1116         $tpl->newTemplate('vhost.conf.master');
ac933e 1117
fb3339 1118         $vhost_data = $data['new'];
a7bdf8 1119         //unset($vhost_data['ip_address']);
6fb93d 1120         $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder;
M 1121         $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder;
fb3339 1122         $vhost_data['web_basedir'] = $web_config['website_basedir'];
J 1123         $vhost_data['security_level'] = $web_config['security_level'];
1124         $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override'];
1125         $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
1126         $vhost_data['ssl_domain'] = $data['new']['ssl_domain'];
1127         $vhost_data['has_custom_php_ini'] = $has_custom_php_ini;
1128         $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir);
b1a6a5 1129
02bf99 1130         // Custom Apache directives
1fa8f4 1131         if(intval($data['new']['directive_snippets_id']) > 0){
2af58c 1132             $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']);
1fa8f4 1133             if(isset($snippet['snippet'])){
FT 1134                 $vhost_data['apache_directives'] = $snippet['snippet'];
1135             }
1136         }
02bf99 1137         // Make sure we only have Unix linebreaks
T 1138         $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']);
1139         $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']);
6b15d5 1140         $trans = array(
MB 1141             '{DOCROOT}' => $vhost_data['web_document_root_www'],
1142             '{DOCROOT_CLIENT}' => $vhost_data['web_document_root']
1143         );
018955 1144         $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans);
ac933e 1145
46c683 1146         // Check if a SSL cert exists
fb3339 1147         $ssl_dir = $data['new']['document_root'].'/ssl';
J 1148         $domain = $data['new']['ssl_domain'];
394f3e 1149         if(!$domain) $domain = $data['new']['domain'];
fb3339 1150         $key_file = $ssl_dir.'/'.$domain.'.key';
J 1151         $crt_file = $ssl_dir.'/'.$domain.'.crt';
1152         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
ac933e 1153
a7bdf8 1154         /*
1a2310 1155         if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
fb3339 1156             $vhost_data['ssl_enabled'] = 1;
J 1157             $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
46c683 1158         } else {
fb3339 1159             $vhost_data['ssl_enabled'] = 0;
1a2310 1160             $app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG);
46c683 1161         }
a7bdf8 1162         */
ac933e 1163
50306f 1164         if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y') {
46230b 1165             if(substr($domain, 0, 2) === '*.') {
MC 1166                 // wildcard domain not yet supported by letsencrypt!
1167                 $app->log('Wildcard domains not yet supported by letsencrypt, so changing ' . $domain . ' to ' . substr($domain, 2), LOGLEVEL_WARN);
1168                 $domain = substr($domain, 2);
1169             }
1170             
018c55 1171             $data['new']['ssl_domain'] = $domain;
MC 1172             $vhost_data['ssl_domain'] = $domain;
50306f 1173         }
018c55 1174
50306f 1175         //* Generate Let's Encrypt SSL certificat
MB 1176         if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && ( // ssl and let's encrypt is active
1177             ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration
1178             || ($data['old']['domain'] != $data['new']['domain']) // we have domain update
1179             || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain
1180             || ($data['new']['type'] == 'subdomain') // we have new or update on subdomain
1181             || ($data['old']['type'] == 'alias' || $data['new']['type'] == 'alias') // we have new or update on aliasdomain
1182         )) {
a20ec4 1183             // default values
MB 1184             $temp_domains = array();
1185             $lddomain = $domain;
1186             $subdomains = null;
1ba089 1187             $aliasdomains = null;
34c940 1188             $sub_prefixes = array();
a20ec4 1189
018c55 1190             //* be sure to have good domain
MC 1191             if($data['new']['subdomain'] == "www" OR $data['new']['subdomain'] == "*") {
a20ec4 1192                 $temp_domains[] = "www." . $domain;
018c55 1193             }
MC 1194
a20ec4 1195             //* then, add subdomain if we have
MB 1196             $subdomains = $app->db->queryAllRecords('SELECT domain FROM web_domain WHERE parent_domain_id = '.intval($data['new']['domain_id'])." AND active = 'y' AND type = 'subdomain'");
1197             if(is_array($subdomains)) {
1198                 foreach($subdomains as $subdomain) {
1199                     $temp_domains[] = $subdomain['domain'];
34c940 1200                     $sub_prefixes[] = str_replace($domain, "", $subdomain['domain']);
a20ec4 1201                 }
MB 1202             }
1ba089 1203             
MB 1204             //* then, add alias domain if we have
1205             $aliasdomains = $app->db->queryAllRecords('SELECT domain,subdomain FROM web_domain WHERE parent_domain_id = '.intval($data['new']['domain_id'])." AND active = 'y' AND type = 'alias'");
1206             if(is_array($aliasdomains)) {
1207                 foreach($aliasdomains as $aliasdomain) {
1208                     $temp_domains[] = $aliasdomain['domain'];
1209                     if(isset($aliasdomain['subdomain']) && ! empty($aliasdomain['subdomain'])) {
1210                         $temp_domains[] = $aliasdomain['subdomain'] . "." . $aliasdomain['domain'];
1211                     }
1212                 }
1213             }
018c55 1214
a20ec4 1215             // prevent duplicate
MB 1216             $temp_domains = array_unique($temp_domains);
018c55 1217
a20ec4 1218             // generate cli format
MB 1219             foreach($temp_domains as $temp_domain) {
1220                 $lddomain .= (string) " --domains " . $temp_domain;
1221             }
018c55 1222
a20ec4 1223             // useless data
MB 1224             unset($subdomains);
1225             unset($temp_domains);
018c55 1226
a20ec4 1227             $crt_tmp_file = "/etc/letsencrypt/live/".$domain."/cert.pem";
MB 1228             $key_tmp_file = "/etc/letsencrypt/live/".$domain."/privkey.pem";
1229             $bundle_tmp_file = "/etc/letsencrypt/live/".$domain."/chain.pem";
1230             $webroot = $data['new']['document_root']."/web";
018c55 1231
a20ec4 1232             //* check if we have already a Let's Encrypt cert
MB 1233             if(!file_exists($crt_tmp_file) && !file_exists($key_tmp_file)) {
1234                 $app->log("Create Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG);
551d9a 1235                 
MB 1236                 $success = false;
a20ec4 1237                 if(file_exists("/root/.local/share/letsencrypt/bin/letsencrypt")) {
551d9a 1238                     $success = $this->_exec("/root/.local/share/letsencrypt/bin/letsencrypt auth --text --agree-tos --authenticator webroot --server https://acme-v01.api.letsencrypt.org/directory --rsa-key-size 4096 --email postmaster@$domain --domains $lddomain --webroot-path /usr/local/ispconfig/interface/acme");
018c55 1239                 }
551d9a 1240                 if(!$success) {
MB 1241                     // error issuing cert
1242                     $app->log('Let\'s Encrypt SSL Cert for: ' . $domain . ' could not be issued.', LOGLEVEL_WARN);
1243                     $data['new']['ssl_letsencrypt'] = 'n';
1244                     if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n';
1245                     /* Update the DB of the (local) Server */
1246                     $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']);
1247                     /* Update also the master-DB of the Server-Farm */
1248                     $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']);
1249                 }
1250             }
018c55 1251
a20ec4 1252             //* check is been correctly created
MB 1253             if(file_exists($crt_tmp_file) OR file_exists($key_tmp_file)) {
1254                 $date = date("YmdHis");
1255                 if(is_file($key_file)) {
1256                     $app->system->copy($key_file, $key_file.'.old'.$date);
1257                     $app->system->chmod($key_file.'.old.'.$date, 0400);
1258                     $app->system->unlink($key_file);
1259                 }
1260
1261                 if ($web_config["website_symlinks_rel"] == 'y') {
1262                     $this->create_relative_link(escapeshellcmd($key_tmp_file), escapeshellcmd($key_file));
1263                 } else {
1264                     exec("ln -s ".escapeshellcmd($key_tmp_file)." ".escapeshellcmd($key_file));
1265                 }
1266
1267                 if(is_file($crt_file)) {
1268                     $app->system->copy($crt_file, $crt_file.'.old.'.$date);
1269                     $app->system->chmod($crt_file.'.old.'.$date, 0400);
1270                     $app->system->unlink($crt_file);
1271                 }
1272
1273                 if($web_config["website_symlinks_rel"] == 'y') {
1274                     $this->create_relative_link(escapeshellcmd($crt_tmp_file), escapeshellcmd($crt_file));
1275                 } else {
1276                     exec("ln -s ".escapeshellcmd($crt_tmp_file)." ".escapeshellcmd($crt_file));
1277                 }
1278
1279                 if(is_file($bundle_file)) {
1280                     $app->system->copy($bundle_file, $bundle_file.'.old.'.$date);
1281                     $app->system->chmod($bundle_file.'.old.'.$date, 0400);
1282                     $app->system->unlink($bundle_file);
1283                 }
1284
1285                 if($web_config["website_symlinks_rel"] == 'y') {
1286                     $this->create_relative_link(escapeshellcmd($bundle_tmp_file), escapeshellcmd($bundle_file));
1287                 } else {
1288                     exec("ln -s ".escapeshellcmd($bundle_tmp_file)." ".escapeshellcmd($bundle_file));
1289                 }
1290
1291                 /* we don't need to store it.
1292                 /* Update the DB of the (local) Server */
551d9a 1293                 $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']);
MB 1294                 $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
a20ec4 1295                 /* Update also the master-DB of the Server-Farm */
551d9a 1296                 $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']);
MB 1297                 $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
a20ec4 1298             }
MB 1299         }
1300
46c683 1301         if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1;
ac933e 1302
6fb93d 1303         //$vhost_data['document_root'] = $data['new']['document_root'].'/' . $web_folder;
b1a6a5 1304
e64fbb 1305         // Set SEO Redirect
bfcdef 1306         if($data['new']['seo_redirect'] != ''){
e64fbb 1307             $vhost_data['seo_redirect_enabled'] = 1;
bfcdef 1308             $tmp_seo_redirects = $this->get_seo_redirects($data['new']);
T 1309             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1310                 foreach($tmp_seo_redirects as $key => $val){
1311                     $vhost_data[$key] = $val;
1312                 }
1313             } else {
1314                 $vhost_data['seo_redirect_enabled'] = 0;
e64fbb 1315             }
F 1316         } else {
1317             $vhost_data['seo_redirect_enabled'] = 0;
1318         }
b1a6a5 1319
46c683 1320         $tpl->setVar($vhost_data);
8133de 1321         $tpl->setVar('apache_version', $app->system->getapacheversion());
ac933e 1322
46c683 1323         // Rewrite rules
T 1324         $rewrite_rules = array();
a639ee 1325         $rewrite_wildcard_rules = array();
02bf99 1326         if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') {
b1a6a5 1327             if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/';
MC 1328             if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){
1329                 $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8);
1330                 $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8);
45ee67 1331             } else {
F 1332                 $rewrite_target = $data['new']['redirect_path'];
1333                 $rewrite_target_ssl = $data['new']['redirect_path'];
1334             }
bc2c3e 1335             /* Disabled path extension
fb3339 1336             if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
J 1337                 $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
8388ae 1338             }
bc2c3e 1339             */
ac933e 1340
fb3339 1341             switch($data['new']['subdomain']) {
b1a6a5 1342             case 'www':
MC 1343                 $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
1344                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
1345                     'rewrite_target'  => $rewrite_target,
1346                     'rewrite_target_ssl' => $rewrite_target_ssl,
1347                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1348                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1349                 $rewrite_rules[] = array( 'rewrite_domain'  => '^' . $this->_rewrite_quote('www.'.$data['new']['domain']),
1350                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
1351                     'rewrite_target'  => $rewrite_target,
1352                     'rewrite_target_ssl' => $rewrite_target_ssl,
1353                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1354                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1355                 break;
1356             case '*':
a639ee 1357                 $rewrite_wildcard_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']),
b1a6a5 1358                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
MC 1359                     'rewrite_target'  => $rewrite_target,
1360                     'rewrite_target_ssl' => $rewrite_target_ssl,
1361                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1362                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1363                 break;
1364             default:
1365                 $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
1366                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
1367                     'rewrite_target'  => $rewrite_target,
1368                     'rewrite_target_ssl' => $rewrite_target_ssl,
1369                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1370                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1371             }
46c683 1372         }
b1a6a5 1373
3501f9 1374         $server_alias = array();
b1a6a5 1375
3501f9 1376         // get autoalias
M 1377         $auto_alias = $web_config['website_autoalias'];
1378         if($auto_alias != '') {
1379             // get the client username
2af58c 1380             $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id);
3501f9 1381             $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]');
M 1382             $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']);
1383             $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias);
1384             unset($client);
1385             unset($aa_search);
1386             unset($aa_replace);
cece69 1387             $server_alias[] .= $auto_alias.' ';
3501f9 1388         }
b1a6a5 1389
46c683 1390         // get alias domains (co-domains and subdomains)
2af58c 1391         $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']);
bfcdef 1392         $alias_seo_redirects = array();
fb3339 1393         switch($data['new']['subdomain']) {
b1a6a5 1394         case 'www':
MC 1395             $server_alias[] .= 'www.'.$data['new']['domain'].' ';
1396             break;
1397         case '*':
1398             $server_alias[] .= '*.'.$data['new']['domain'].' ';
1399             break;
ac933e 1400         }
46c683 1401         if(is_array($aliases)) {
T 1402             foreach($aliases as $alias) {
fb3339 1403                 switch($alias['subdomain']) {
b1a6a5 1404                 case 'www':
MC 1405                     $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain'].' ';
1406                     break;
1407                 case '*':
1408                     $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain'].' ';
1409                     break;
1410                 default:
1411                     $server_alias[] .= $alias['domain'].' ';
1412                     break;
ac933e 1413                 }
b1a6a5 1414                 $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG);
MC 1415
bfcdef 1416                 // Add SEO redirects for alias domains
T 1417                 if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){
1418                     $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_');
1419                     if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1420                         $alias_seo_redirects[] = $tmp_seo_redirects;
1421                     }
1422                 }
b1a6a5 1423
46c683 1424                 // Rewriting
02bf99 1425                 if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') {
b1a6a5 1426                     if(substr($alias['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $alias['redirect_path'])) $alias['redirect_path'] .= '/';
MC 1427                     if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){
1428                         $rewrite_target = 'http'.substr($alias['redirect_path'], 8);
1429                         $rewrite_target_ssl = 'https'.substr($alias['redirect_path'], 8);
e64fbb 1430                     } else {
F 1431                         $rewrite_target = $alias['redirect_path'];
1432                         $rewrite_target_ssl = $alias['redirect_path'];
1433                     }
bc2c3e 1434                     /* Disabled the path extension
fb3339 1435                     if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
J 1436                         $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
8388ae 1437                     }
bc2c3e 1438                     */
b1a6a5 1439
fb3339 1440                     switch($alias['subdomain']) {
b1a6a5 1441                     case 'www':
MC 1442                         $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($alias['domain']),
1443                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1444                             'rewrite_target'  => $rewrite_target,
1445                             'rewrite_target_ssl' => $rewrite_target_ssl,
1446                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1447                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1448                         $rewrite_rules[] = array( 'rewrite_domain'  => '^' . $this->_rewrite_quote('www.'.$alias['domain']),
1449                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1450                             'rewrite_target'  => $rewrite_target,
1451                             'rewrite_target_ssl' => $rewrite_target_ssl,
1452                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1453                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1454                         break;
1455                     case '*':
a639ee 1456                         $rewrite_wildcard_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($alias['domain']),
b1a6a5 1457                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
MC 1458                             'rewrite_target'  => $rewrite_target,
1459                             'rewrite_target_ssl' => $rewrite_target_ssl,
1460                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1461                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1462                         break;
1463                     default:
1464                         if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2));
1465                         else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']);
1466                         $rewrite_rules[] = array( 'rewrite_domain'  => $domain_rule,
1467                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1468                             'rewrite_target'  => $rewrite_target,
1469                             'rewrite_target_ssl' => $rewrite_target_ssl,
1470                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1471                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1472                     }
46c683 1473                 }
T 1474             }
1475         }
ac933e 1476
47cca9 1477         //* If we have some alias records
T 1478         if(count($server_alias) > 0) {
1479             $server_alias_str = '';
1480             $n = 0;
ac933e 1481
47cca9 1482             // begin a new ServerAlias line after 30 alias domains
T 1483             foreach($server_alias as $tmp_alias) {
1484                 if($n % 30 == 0) $server_alias_str .= "\n    ServerAlias ";
1485                 $server_alias_str .= $tmp_alias;
1486             }
1487             unset($tmp_alias);
ac933e 1488
b1a6a5 1489             $tpl->setVar('alias', trim($server_alias_str));
47cca9 1490         } else {
b1a6a5 1491             $tpl->setVar('alias', '');
47cca9 1492         }
a639ee 1493         
D 1494         if (count($rewrite_wildcard_rules) > 0) $rewrite_rules = array_merge($rewrite_rules, $rewrite_wildcard_rules); // Append wildcard rules to the end of rules
ac933e 1495
bfcdef 1496         if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0) {
b1a6a5 1497             $tpl->setVar('rewrite_enabled', 1);
46c683 1498         } else {
b1a6a5 1499             $tpl->setVar('rewrite_enabled', 0);
bfcdef 1500         }
8ab3cd 1501
T 1502         //$tpl->setLoop('redirects',$rewrite_rules);
ac933e 1503
V 1504         /**
1505          * install fast-cgi starter script and add script aliasd config
46c683 1506          * first we create the script directory if not already created, then copy over the starter script
T 1507          * settings are copied over from the server ini config for now
1508          * TODO: Create form for fastcgi configs per site.
1509          */
ac933e 1510
b1a6a5 1511
fb3339 1512         if ($data['new']['php'] == 'fast-cgi') {
ac933e 1513
b1a6a5 1514             $fastcgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $fastcgi_config['fastcgi_starter_path']);
MC 1515             $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path);
ac933e 1516
V 1517             if (!is_dir($fastcgi_starter_path)) {
c77103 1518                 $app->system->mkdirpath($fastcgi_starter_path);
fb3339 1519                 //exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
ac933e 1520
V 1521
b1a6a5 1522                 $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path, LOGLEVEL_DEBUG);
46c683 1523             }
ac933e 1524
c77103 1525             //exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
b1a6a5 1526             $app->system->chown($fastcgi_starter_path, $data['new']['system_user']);
MC 1527             $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']);
1528
46c683 1529             $fcgi_tpl = new tpl();
fb3339 1530             $fcgi_tpl->newTemplate('php-fcgi-starter.master');
8133de 1531             $fcgi_tpl->setVar('apache_version', $app->system->getapacheversion());
b1a6a5 1532
62b385 1533             // Support for multiple PHP versions (FastCGI)
F 1534             if(trim($data['new']['fastcgi_php_version']) != ''){
1535                 $default_fastcgi_php = false;
b1a6a5 1536                 if(substr($custom_fastcgi_php_ini_dir, -1) != '/') $custom_fastcgi_php_ini_dir .= '/';
62b385 1537             } else {
F 1538                 $default_fastcgi_php = true;
1539             }
b1a6a5 1540
7fddfe 1541             if($has_custom_php_ini) {
b1a6a5 1542                 $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir));
7fddfe 1543             } else {
62b385 1544                 if($default_fastcgi_php){
b1a6a5 1545                     $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
62b385 1546                 } else {
b1a6a5 1547                     $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_fastcgi_php_ini_dir));
62b385 1548                 }
7fddfe 1549             }
b1a6a5 1550             $fcgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
MC 1551             $fcgi_tpl->setVar('php_fcgi_children', escapeshellcmd($fastcgi_config['fastcgi_children']));
1552             $fcgi_tpl->setVar('php_fcgi_max_requests', escapeshellcmd($fastcgi_config['fastcgi_max_requests']));
62b385 1553             if($default_fastcgi_php){
b1a6a5 1554                 $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($fastcgi_config['fastcgi_bin']));
62b385 1555             } else {
b1a6a5 1556                 $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable));
62b385 1557             }
b1a6a5 1558             $fcgi_tpl->setVar('security_level', intval($web_config['security_level']));
f63910 1559             $fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain']));
ac933e 1560
fb3339 1561             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ff7075 1562             $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
ac933e 1563
511ba5 1564             $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''));
b1a6a5 1565             $app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab());
46c683 1566             unset($fcgi_tpl);
ac933e 1567
b1a6a5 1568             $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG);
ac933e 1569
b1a6a5 1570             $app->system->chmod($fcgi_starter_script, 0755);
MC 1571             $app->system->chown($fcgi_starter_script, $data['new']['system_user']);
1572             $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']);
1573
1574             $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']);
1575             $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path);
511ba5 1576             $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''));
b1a6a5 1577             $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']);
MC 1578             $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']);
ac933e 1579
62e4b3 1580         } else {
F 1581             //remove the php fastgi starter script if available
b5b862 1582             $fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : '');
62e4b3 1583             if ($data['old']['php'] == 'fast-cgi') {
b1a6a5 1584                 $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']);
MC 1585                 $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path);
1586                 if($data['old']['type'] == 'vhost') {
b5b862 1587                     if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script);
TB 1588                     if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path);
b1a6a5 1589                 } else {
b5b862 1590                     if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script);
b1a6a5 1591                 }
62e4b3 1592             }
46c683 1593         }
b1a6a5 1594
MC 1595
1596
274362 1597         /**
b1a6a5 1598          * PHP-FPM
MC 1599          */
274362 1600         // Support for multiple PHP versions
02e7ea 1601         if($data['new']['php'] == 'php-fpm'){
62e4b3 1602             if(trim($data['new']['fastcgi_php_version']) != ''){
F 1603                 $default_php_fpm = false;
1604                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
b1a6a5 1605                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 1606             } else {
F 1607                 $default_php_fpm = true;
1608             }
274362 1609         } else {
c59632 1610             if(trim($data['old']['fastcgi_php_version']) != '' && ($data['old']['php'] == 'php-fpm' || $data['old']['php'] == 'hhvm')){
62e4b3 1611                 $default_php_fpm = false;
F 1612                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
b1a6a5 1613                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 1614             } else {
F 1615                 $default_php_fpm = true;
1616             }
274362 1617         }
b1a6a5 1618
274362 1619         if($default_php_fpm){
F 1620             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
1621         } else {
1622             $pool_dir = $custom_php_fpm_pool_dir;
1623         }
ab79c2 1624         $pool_dir = trim($pool_dir);
b1a6a5 1625         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
274362 1626         $pool_name = 'web'.$data['new']['domain_id'];
F 1627         $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
b1a6a5 1628         if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
9b021b 1629         
1e67c1 1630         $apache_modules = $app->system->getapachemodules();
TB 1631         
1632         // Use sockets, but not with apache 2.4 on centos (mod_proxy_fcgi) as socket support is buggy in that version
1633         if($data['new']['php_fpm_use_socket'] == 'y' && in_array('fastcgi_module',$apache_modules)){
274362 1634             $use_tcp = 0;
F 1635             $use_socket = 1;
1636         } else {
1637             $use_tcp = 1;
1638             $use_socket = 0;
1639         }
1640         $tpl->setVar('use_tcp', $use_tcp);
1641         $tpl->setVar('use_socket', $use_socket);
1642         $fpm_socket = $socket_dir.$pool_name.'.sock';
1643         $tpl->setVar('fpm_socket', $fpm_socket);
1644         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
ac933e 1645
46c683 1646         /**
T 1647          * install cgi starter script and add script alias to config.
1648          * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!)
1649          * first we create the script directory if not already created, then copy over the starter script.
1650          * TODO: we have to fetch the data from the server-settings.
1651          */
fb3339 1652         if ($data['new']['php'] == 'cgi') {
J 1653             //$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi');
46c683 1654
fb3339 1655             $cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
511ba5 1656             $cgi_config['cgi_starter_script'] = 'php-cgi-starter'.(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '');
fb3339 1657             $cgi_config['cgi_bin'] = '/usr/bin/php-cgi';
46c683 1658
b1a6a5 1659             $cgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $cgi_config['cgi_starter_path']);
MC 1660             $cgi_starter_path = str_replace('[client_id]', $client_id, $cgi_starter_path);
46c683 1661
ac933e 1662             if (!is_dir($cgi_starter_path)) {
c77103 1663                 $app->system->mkdirpath($cgi_starter_path);
b1a6a5 1664                 $app->system->chown($cgi_starter_path, $data['new']['system_user']);
MC 1665                 $app->system->chgrp($cgi_starter_path, $data['new']['system_group']);
1666                 $app->system->chmod($cgi_starter_path, 0755);
46c683 1667
b1a6a5 1668                 $app->log('Creating cgi starter script directory: '.$cgi_starter_path, LOGLEVEL_DEBUG);
46c683 1669             }
T 1670
1671             $cgi_tpl = new tpl();
fb3339 1672             $cgi_tpl->newTemplate('php-cgi-starter.master');
8133de 1673             $cgi_tpl->setVar('apache_version', $app->system->getapacheversion());
46c683 1674
fb3339 1675             // This works because PHP "rewrites" a symlink to the physical path
J 1676             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ac933e 1677             $cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
fb3339 1678             $cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
ac933e 1679
46c683 1680             // This will NOT work!
fb3339 1681             //$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']);
b1a6a5 1682             $cgi_tpl->setVar('php_cgi_bin', $cgi_config['cgi_bin']);
MC 1683             $cgi_tpl->setVar('security_level', $web_config['security_level']);
1684
1685             $cgi_tpl->setVar('has_custom_php_ini', $has_custom_php_ini);
7fddfe 1686             if($has_custom_php_ini) {
b1a6a5 1687                 $cgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir));
7fddfe 1688             } else {
b1a6a5 1689                 $cgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
7fddfe 1690             }
46c683 1691
511ba5 1692             $cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''));
b1a6a5 1693             $app->system->file_put_contents($cgi_starter_script, $cgi_tpl->grab());
46c683 1694             unset($cgi_tpl);
T 1695
b1a6a5 1696             $app->log('Creating cgi starter script: '.$cgi_starter_script, LOGLEVEL_DEBUG);
46c683 1697
T 1698
b1a6a5 1699             $app->system->chmod($cgi_starter_script, 0755);
MC 1700             $app->system->chown($cgi_starter_script, $data['new']['system_user']);
1701             $app->system->chgrp($cgi_starter_script, $data['new']['system_group']);
46c683 1702
b1a6a5 1703             $tpl->setVar('cgi_starter_path', $cgi_starter_path);
511ba5 1704             $tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''));
46c683 1705
T 1706         }
1707
fb3339 1708         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost');
7ed741 1709         //* Make a backup copy of vhost file
b1a6a5 1710         if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~');
MC 1711
a7bdf8 1712         //* create empty vhost array
T 1713         $vhosts = array();
b1a6a5 1714
526b99 1715         //* Add vhost for ipv4 IP
6c424f 1716
FS 1717         //* use ip-mapping for web-mirror
1718         if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) {
1719             $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?";
1720             $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']);
1721             $data['new']['ip_address'] = $newip['destination_ip'];
1722             unset($newip);
1723         }
1724
526b99 1725         $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
T 1726         if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1727         if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1728         $vhosts[] = $tmp_vhost_arr;
1729         unset($tmp_vhost_arr);
b1a6a5 1730
a7bdf8 1731         //* Add vhost for ipv4 IP with SSL
481c00 1732         $ssl_dir = $data['new']['document_root'].'/ssl';
T 1733         $domain = $data['new']['ssl_domain'];
1734         $key_file = $ssl_dir.'/'.$domain.'.key';
1735         $crt_file = $ssl_dir.'/'.$domain.'.crt';
b1a6a5 1736
a7bdf8 1737         if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
526b99 1738             $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443');
T 1739             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
cc6568 1740             $ipv4_ssl_alias_seo_redirects = $alias_seo_redirects;
H 1741             if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){
1742                 for($i=0;$i<count($ipv4_ssl_alias_seo_redirects);$i++){
1743                     $ipv4_ssl_alias_seo_redirects[$i]['ssl_enabled'] = 1;
1744                 }
1745             }
1746             if(count($ipv4_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects);
526b99 1747             $vhosts[] = $tmp_vhost_arr;
cc6568 1748             unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects);
b1a6a5 1749             $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG);
bd68aa 1750         }
MC 1751
b1a6a5 1752         //* Add vhost for IPv6 IP
MC 1753         if($data['new']['ipv6_address'] != '') {
fbeb11 1754             //* rewrite ipv6 on mirrors
FS 1755             /* chang $conf to $web_config */
1756             if ($web_config['serverconfig']['web']['vhost_rewrite_v6'] == 'y') {
1757                 if (isset($web_config['serverconfig']['server']['v6_prefix']) && $web_config['serverconfig']['server']['v6_prefix'] <> '') {
1758                     $explode_v6prefix=explode(':', $web_config['serverconfig']['server']['v6_prefix']);
b1a6a5 1759                     $explode_v6=explode(':', $data['new']['ipv6_address']);
MC 1760
1761                     for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) {
1762                         $explode_v6[$i] = $explode_v6prefix[$i];
1763                     }
1764                     $data['new']['ipv6_address'] = implode(':', $explode_v6);
bd68aa 1765                 }
MC 1766             }
96f31d 1767             if($data['new']['ipv6_address'] == '*') $data['new']['ipv6_address'] = '::';
526b99 1768             $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
T 1769             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1770             if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1771             $vhosts[] = $tmp_vhost_arr;
1772             unset($tmp_vhost_arr);
b1a6a5 1773
a7bdf8 1774             //* Add vhost for ipv6 IP with SSL
T 1775             if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
526b99 1776                 $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443');
T 1777                 if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
cc6568 1778                 $ipv6_ssl_alias_seo_redirects = $alias_seo_redirects;
H 1779                 if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){
1780                     for($i=0;$i<count($ipv6_ssl_alias_seo_redirects);$i++){
1781                         $ipv6_ssl_alias_seo_redirects[$i]['ssl_enabled'] = 1;
1782                     }
1783                 }
1784                 if(count($ipv6_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects);
526b99 1785                 $vhosts[] = $tmp_vhost_arr;
cc6568 1786                 unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects);
b1a6a5 1787                 $app->log('Enable SSL for IPv6: '.$domain, LOGLEVEL_DEBUG);
a7bdf8 1788             }
T 1789         }
b1a6a5 1790
a7bdf8 1791         //* Set the vhost loop
b1a6a5 1792         $tpl->setLoop('vhosts', $vhosts);
MC 1793
7ed741 1794         //* Write vhost file
b1a6a5 1795         $app->system->file_put_contents($vhost_file, $tpl->grab());
MC 1796         $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1797         unset($tpl);
ac933e 1798
V 1799         /*
1800          * maybe we have some webdav - user. If so, add them...
1801         */
fb3339 1802         $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav');
ac933e 1803
c6a89c 1804         //* Set the symlink to enable the vhost
T 1805         //* First we check if there is a old type of symlink and remove it
fb3339 1806         $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost');
c77103 1807         if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink);
b1a6a5 1808
c6a89c 1809         //* Remove old or changed symlinks
T 1810         if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') {
1811             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1812             if(is_link($vhost_symlink)) {
c77103 1813                 $app->system->unlink($vhost_symlink);
b1a6a5 1814                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1815             }
T 1816             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1817             if(is_link($vhost_symlink)) {
c77103 1818                 $app->system->unlink($vhost_symlink);
b1a6a5 1819                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1820             }
T 1821         }
b1a6a5 1822
c6a89c 1823         //* New symlink
T 1824         if($data['new']['subdomain'] == '*') {
1825             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1826         } else {
1827             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1828         }
fb3339 1829         if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) {
b1a6a5 1830             symlink($vhost_file, $vhost_symlink);
MC 1831             $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
46c683 1832         }
ac933e 1833
46c683 1834         // remove old symlink and vhost file, if domain name of the site has changed
fb3339 1835         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
c6a89c 1836             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
T 1837             if(is_link($vhost_symlink)) {
c77103 1838                 $app->system->unlink($vhost_symlink);
b1a6a5 1839                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1840             }
T 1841             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1842             if(is_link($vhost_symlink)) {
c77103 1843                 $app->system->unlink($vhost_symlink);
b1a6a5 1844                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1845             }
8cf78b 1846             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 1847             if(is_link($vhost_symlink)) {
c77103 1848                 $app->system->unlink($vhost_symlink);
b1a6a5 1849                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8cf78b 1850             }
fb3339 1851             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
c77103 1852             $app->system->unlink($vhost_file);
b1a6a5 1853             $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1854         }
ac933e 1855
46c683 1856         //* Create .htaccess and .htpasswd file for website statistics
cc6568 1857         //if(!is_file($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) {
H 1858         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats');
1859         $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user";
b1a6a5 1860         $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file);
MC 1861         $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755);
cc6568 1862         unset($ht_file);
H 1863         //}
ac933e 1864
bfcdef 1865         if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
fb3339 1866             if(trim($data['new']['stats_password']) != '') {
J 1867                 $htp_file = 'admin:'.trim($data['new']['stats_password']);
b1a6a5 1868                 $app->system->web_folder_protection($data['new']['document_root'], false);
MC 1869                 $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file);
1870                 $app->system->web_folder_protection($data['new']['document_root'], true);
1871                 $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755);
46c683 1872                 unset($htp_file);
T 1873             }
1874         }
b1a6a5 1875
58c210 1876         //* Create awstats configuration
511ba5 1877         if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) {
b1a6a5 1878             $this->awstats_update($data, $web_config);
58c210 1879         }
b1a6a5 1880
MC 1881         $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir);
c59632 1882         $this->hhvm_update($data, $web_config);
b1a6a5 1883
7ed741 1884         if($web_config['check_apache_config'] == 'y') {
T 1885             //* Test if apache starts with the new configuration file
b1a6a5 1886             $apache_online_status_before_restart = $this->_checkTcp('localhost', 80);
MC 1887             $app->log('Apache status is: '.($apache_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
ac933e 1888
b1a6a5 1889             $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure
MC 1890             $app->log('Apache restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG);
1891
9f56bd 1892             // wait a few seconds, before we test the apache status again
bfcdef 1893             $apache_online_status_after_restart = false;
9f56bd 1894             sleep(2);
bfcdef 1895             for($i = 0; $i < 5; $i++) {
b1a6a5 1896                 $apache_online_status_after_restart = $this->_checkTcp('localhost', 80);
bfcdef 1897                 if($apache_online_status_after_restart) break;
T 1898                 sleep(1);
1899             }
7ed741 1900             //* Check if apache restarted successfully if it was online before
b1a6a5 1901             $app->log('Apache online status after restart is: '.($apache_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
615a0a 1902             if($apache_online_status_before_restart && !$apache_online_status_after_restart || $retval['retval'] > 0) {
b1a6a5 1903                 $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN);
615a0a 1904                 if(is_array($retval['output']) && !empty($retval['output'])){
b1a6a5 1905                     $app->log('Reason for Apache restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN);
7b47c0 1906                     $app->dbmaster->datalogError(implode("\n", $retval['output']));
615a0a 1907                 } else {
T 1908                     // if no output is given, check again
1909                     $webserver_binary = '';
7b47c0 1910                     exec('which apache2ctl', $webserver_check_output, $webserver_check_retval);
615a0a 1911                     if($webserver_check_retval == 0){
7b47c0 1912                         $webserver_binary = 'apache2ctl';
615a0a 1913                     } else {
T 1914                         unset($webserver_check_output, $webserver_check_retval);
7b47c0 1915                         exec('which apache2', $webserver_check_output, $webserver_check_retval);
615a0a 1916                         if($webserver_check_retval == 0){
7b47c0 1917                             $webserver_binary = 'apache2';
615a0a 1918                         } else {
T 1919                             unset($webserver_check_output, $webserver_check_retval);
7b47c0 1920                             exec('which httpd2', $webserver_check_output, $webserver_check_retval);
615a0a 1921                             if($webserver_check_retval == 0){
7b47c0 1922                                 $webserver_binary = 'httpd2';
615a0a 1923                             } else {
T 1924                                 unset($webserver_check_output, $webserver_check_retval);
7b47c0 1925                                 exec('which httpd', $webserver_check_output, $webserver_check_retval);
615a0a 1926                                 if($webserver_check_retval == 0){
7b47c0 1927                                     $webserver_binary = 'httpd';
T 1928                                 } else {
1929                                     unset($webserver_check_output, $webserver_check_retval);
1930                                     exec('which apache', $webserver_check_output, $webserver_check_retval);
1931                                     if($webserver_check_retval == 0){
1932                                         $webserver_binary = 'apache';
1933                                     }
615a0a 1934                                 }
T 1935                             }
1936                         }
1937                     }
1938                     if($webserver_binary != ''){
1939                         exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval);
7b47c0 1940                         if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){
b1a6a5 1941                             $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN);
7b47c0 1942                             $app->dbmaster->datalogError(implode("\n", $tmp_output));
T 1943                         }
615a0a 1944                         unset($tmp_output, $tmp_retval);
T 1945                     }
1946                 }
b1a6a5 1947                 $app->system->copy($vhost_file, $vhost_file.'.err');
8cf78b 1948                 if(is_file($vhost_file.'~')) {
T 1949                     //* Copy back the last backup file
b1a6a5 1950                     $app->system->copy($vhost_file.'~', $vhost_file);
8cf78b 1951                 } else {
T 1952                     //* There is no backup file, so we create a empty vhost file with a warning message inside
b1a6a5 1953                     $app->system->file_put_contents($vhost_file, "# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors.");
8cf78b 1954                 }
481c00 1955                 if($this->ssl_certificate_changed === true) {
T 1956
1957                     $ssl_dir = $data['new']['document_root'].'/ssl';
1958                     $domain = $data['new']['ssl_domain'];
1959                     $key_file = $ssl_dir.'/'.$domain.'.key.org';
1960                     $key_file2 = $ssl_dir.'/'.$domain.'.key';
1961                     $csr_file = $ssl_dir.'/'.$domain.'.csr';
1962                     $crt_file = $ssl_dir.'/'.$domain.'.crt';
1963                     $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
b1a6a5 1964
481c00 1965                     //* Backup the files that might have caused the error
43b345 1966                     if(is_file($key_file)){
b1a6a5 1967                         $app->system->copy($key_file, $key_file.'.err');
MC 1968                         $app->system->chmod($key_file.'.err', 0400);
43b345 1969                     }
T 1970                     if(is_file($key_file2)){
b1a6a5 1971                         $app->system->copy($key_file2, $key_file2.'.err');
MC 1972                         $app->system->chmod($key_file2.'.err', 0400);
43b345 1973                     }
b1a6a5 1974                     if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err');
MC 1975                     if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err');
1976                     if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err');
1977
481c00 1978                     //* Restore the ~ backup files
b1a6a5 1979                     if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file);
MC 1980                     if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2);
1981                     if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file);
1982                     if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file);
1983                     if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file);
1984
1985                     $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN);
481c00 1986                 }
b1a6a5 1987
MC 1988                 $app->services->restartService('httpd', 'restart');
7ed741 1989             }
c82dc7 1990         } else {
7ed741 1991             //* We do not check the apache config after changes (is faster)
T 1992             if($apache_chrooted) {
b1a6a5 1993                 $app->services->restartServiceDelayed('httpd', 'restart');
7ed741 1994             } else {
T 1995                 // request a httpd reload when all records have been processed
b1a6a5 1996                 $app->services->restartServiceDelayed('httpd', 'reload');
7ed741 1997             }
c82dc7 1998         }
b1a6a5 1999
MC 2000         //* The vhost is written and apache has been restarted, so we
481c00 2001         // can reset the ssl changed var to false and cleanup some files
T 2002         $this->ssl_certificate_changed = false;
b1a6a5 2003
481c00 2004         $ssl_dir = $data['new']['document_root'].'/ssl';
T 2005         $domain = $data['new']['ssl_domain'];
2006         $key_file = $ssl_dir.'/'.$domain.'.key.org';
2007         $key_file2 = $ssl_dir.'/'.$domain.'.key';
2008         $csr_file = $ssl_dir.'/'.$domain.'.csr';
2009         $crt_file = $ssl_dir.'/'.$domain.'.crt';
2010         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
b1a6a5 2011
c77103 2012         if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~');
T 2013         if(@is_file($key2_file.'~')) $app->system->unlink($key2_file.'~');
2014         if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~');
2015         if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~');
2016         if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~');
b1a6a5 2017
7ed741 2018         // Remove the backup copy of the config file.
c77103 2019         if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~');
ac933e 2020
da1a7c 2021         //* Unset action to clean it for next processed vhost.
T 2022         $this->action = '';
46c683 2023     }
ac933e 2024
b1a6a5 2025     function delete($event_name, $data) {
46c683 2026         global $app, $conf;
ac933e 2027
46c683 2028         // load the server configuration options
fb3339 2029         $app->uses('getconf');
c09f04 2030         $app->uses('system');
fb3339 2031         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
cc6568 2032         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
b1a6a5 2033
511ba5 2034         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false);
ac933e 2035
2bbc4c 2036         //* Check if this is a chrooted setup
4b72c5 2037         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 2038             $apache_chrooted = true;
T 2039         } else {
2040             $apache_chrooted = false;
2041         }
b1a6a5 2042
fea5e7 2043         //* Remove the mounts
T 2044         $log_folder = 'log';
b1a6a5 2045         $web_folder = '';
511ba5 2046         if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') {
2af58c 2047             $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
526b99 2048             if($tmp['domain'] != ''){
T 2049                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
2050             } else {
2051                 // get log folder from /etc/fstab
2052                 /*
2053                 $bind_mounts = $app->system->file_get_contents('/etc/fstab');
2054                 $bind_mount_lines = explode("\n", $bind_mounts);
2055                 if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){
2056                     foreach($bind_mount_lines as $bind_mount_line){
2057                         $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line);
2058                         $bind_mount_parts = explode(' ', $bind_mount_line);
2059                         if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){
2060                             if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){
2061                                 $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]);
2062                             }
2063                         }
2064                     }
2065                 }
2066                 */
2067                 // we are deleting the parent domain, so we can delete everything in the log directory
2068                 $subdomain_hosts = array();
b1a6a5 2069                 $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..'));
526b99 2070                 if(is_array($files) && !empty($files)){
T 2071                     foreach($files as $file){
2072                         if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){
2073                             $subdomain_hosts[] = $file;
2074                         }
2075                     }
2076                 }
2077             }
b1a6a5 2078             if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){
526b99 2079                 $log_folders = array();
T 2080                 foreach($subdomain_hosts as $subdomain_host){
2081                     $log_folders[] = $log_folder.'/'.$subdomain_host;
2082                 }
2083             } else {
2084                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
2085                 $log_folder .= '/' . $subdomain_host;
2086             }
2087             $web_folder = $data['old']['web_folder'];
b1a6a5 2088             unset($tmp);
526b99 2089             unset($subdomain_hosts);
3cde19 2090         }
b1a6a5 2091
511ba5 2092         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){
526b99 2093             if(is_array($log_folders) && !empty($log_folders)){
T 2094                 foreach($log_folders as $log_folder){
cc6568 2095                     //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
a9b325 2096                     //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
cc6568 2097                     exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
526b99 2098                 }
T 2099             } else {
cc6568 2100                 //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
a9b325 2101                 //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
cc6568 2102                 exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
526b99 2103             }
T 2104         }
b1a6a5 2105
fea5e7 2106         //* remove mountpoint from fstab
526b99 2107         if(is_array($log_folders) && !empty($log_folders)){
T 2108             foreach($log_folders as $log_folder){
2109                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
b1a6a5 2110                 $app->system->removeLine('/etc/fstab', $fstab_line);
526b99 2111             }
T 2112         } else {
2113             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
b1a6a5 2114             $app->system->removeLine('/etc/fstab', $fstab_line);
526b99 2115         }
T 2116         unset($log_folders);
ac933e 2117
511ba5 2118         if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) {
46c683 2119             //* This is a alias domain or subdomain, so we have to update the website instead
fb3339 2120             $parent_domain_id = intval($data['old']['parent_domain_id']);
2af58c 2121             $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id);
fb3339 2122             $data['new'] = $tmp;
J 2123             $data['old'] = $tmp;
46c683 2124             $this->action = 'update';
T 2125             // just run the update function
b1a6a5 2126             $this->update($event_name, $data);
ac933e 2127
46c683 2128         } else {
T 2129             //* This is a website
2130             // Deleting the vhost file, symlink and the data directory
fb3339 2131             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
b1a6a5 2132
8ab3cd 2133             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 2134             if(is_link($vhost_symlink)){
c77103 2135                 $app->system->unlink($vhost_symlink);
b1a6a5 2136                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 2137             }
T 2138             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
2139             if(is_link($vhost_symlink)){
c77103 2140                 $app->system->unlink($vhost_symlink);
b1a6a5 2141                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 2142             }
T 2143             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
2144             if(is_link($vhost_symlink)){
c77103 2145                 $app->system->unlink($vhost_symlink);
b1a6a5 2146                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 2147             }
b1a6a5 2148
c77103 2149             $app->system->unlink($vhost_file);
b1a6a5 2150             $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
ac933e 2151
511ba5 2152             if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') {
b1a6a5 2153                 $docroot = escapeshellcmd($data['old']['document_root']);
MC 2154                 if($docroot != '' && !stristr($docroot, '..')) {
2155                     if($data['old']['type'] == 'vhost') {
2156                         // this is a vhost - we delete everything in here.
2157                         exec('rm -rf '.$docroot);
2158                     } elseif(!stristr($data['old']['web_folder'], '..')) {
2159                         // this is a vhost subdomain
2160                         // IMPORTANT: do some folder checks before we delete this!
2161                         $do_delete = true;
2162                         $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times
2163                         if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1);
2164                         if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1);
46c683 2165
b1a6a5 2166                         $path_elements = explode('/', $delete_folder);
46c683 2167
b1a6a5 2168                         if($path_elements[0] == 'web' || $path_elements[0] === '') {
MC 2169                             // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here!
2170                             // we use strict check as otherwise directories named '0' may not be deleted
2171                             $do_delete = false;
2172                         } else {
511ba5 2173                             // read all vhost subdomains and alias with same parent domain
b1a6a5 2174                             $used_paths = array();
2af58c 2175                             $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']);
b1a6a5 2176                             foreach($tmp as $tmprec) {
MC 2177                                 // we normalize the folder entries because we need to compare them
2178                                 $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times
2179                                 if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1);
2180                                 if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1);
ac933e 2181
b1a6a5 2182                                 // add this path and it's parent paths to used_paths array
MC 2183                                 while(strpos($tmp_folder, '/') !== false) {
2184                                     if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
2185                                     $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/'));
2186                                 }
2187                                 if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
2188                             }
2189                             unset($tmp);
2190
2191                             // loop and check if the path is still used and stop at first used one
2192                             // set do_delete to false so nothing gets deleted if the web_folder itself is still used
2193                             $do_delete = false;
2194                             while(count($path_elements) > 0) {
2195                                 $tmp_folder = implode('/', $path_elements);
2196                                 if(in_array($tmp_folder, $used_paths) == true) break;
2197
2198                                 // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true
2199                                 $delete_folder = $tmp_folder;
2200                                 $do_delete = true;
2201                                 array_pop($path_elements);
2202                             }
2203                             unset($tmp_folder);
2204                             unset($used_paths);
2205                         }
2206
2207                         if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder);
2208
2209                         unset($delete_folder);
2210                         unset($path_elements);
2211                     }
2212                 }
2213
2214                 //remove the php fastgi starter script if available
2215                 if ($data['old']['php'] == 'fast-cgi') {
2216                     $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']);
2217                     if($data['old']['type'] == 'vhost') {
2218                         if (is_dir($fastcgi_starter_path)) {
2219                             exec('rm -rf '.$fastcgi_starter_path);
2220                         }
2221                     } else {
2222                         $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id'];
2223                         if (file_exists($fcgi_starter_script)) {
2224                             exec('rm -f '.$fcgi_starter_script);
2225                         }
2226                     }
2227                 }
2228
2229                 // remove PHP-FPM pool
2230                 if ($data['old']['php'] == 'php-fpm') {
2231                     $this->php_fpm_pool_delete($data, $web_config);
c59632 2232                 } elseif($data['old']['php'] == 'hhvm') {
MC 2233                     $this->hhvm_update($data, $web_config);
b1a6a5 2234                 }
MC 2235
2236                 //remove the php cgi starter script if available
2237                 if ($data['old']['php'] == 'cgi') {
2238                     // TODO: fetch the date from the server-settings
2239                     $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
2240
2241                     $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']);
2242                     if($data['old']['type'] == 'vhost') {
2243                         if (is_dir($cgi_starter_path)) {
2244                             exec('rm -rf '.$cgi_starter_path);
2245                         }
2246                     } else {
2247                         $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id'];
2248                         if (file_exists($cgi_starter_script)) {
2249                             exec('rm -f '.$cgi_starter_script);
2250                         }
2251                     }
2252                 }
2253
2254                 $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG);
2255
2256                 // Delete the symlinks for the sites
2af58c 2257                 $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']);
b1a6a5 2258                 $client_id = intval($client['client_id']);
MC 2259                 unset($client);
2260                 $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
2261                 if(is_array($tmp_symlinks_array)) {
2262                     foreach($tmp_symlinks_array as $tmp_symlink) {
2263                         $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
2264                         $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
2265                         // Remove trailing slash
2266                         if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
2267                         // delete the symlink
2268                         if(is_link($tmp_symlink)) {
2269                             $app->system->unlink($tmp_symlink);
2270                             $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG);
2271                         }
2272                     }
2273                 }
2274                 // end removing symlinks
3cde19 2275             }
b1a6a5 2276
MC 2277             // Delete the log file directory
2278             $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']);
2279             if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir);
2280             $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG);
2281
2282             if($data['old']['type'] == 'vhost') {
2283                 //delete the web user
2284                 $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel';
2285                 $command .= ' '.escapeshellcmd($data['old']['system_user']);
2286                 exec($command);
2287                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
2288
2289             }
2290
2291             //* Remove the awstats configuration file
2292             if($data['old']['stats_type'] == 'awstats') {
2293                 $this->awstats_delete($data, $web_config);
2294             }
2295
511ba5 2296             if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') {
b1a6a5 2297                 $app->system->web_folder_protection($parent_web_document_root, true);
MC 2298             }
2299
8ab3cd 2300             if($apache_chrooted) {
b1a6a5 2301                 $app->services->restartServiceDelayed('httpd', 'restart');
8ab3cd 2302             } else {
T 2303                 // request a httpd reload when all records have been processed
b1a6a5 2304                 $app->services->restartServiceDelayed('httpd', 'reload');
58c210 2305             }
ac933e 2306
0f89bd 2307             //* Delete the web-backups
69b1bc 2308             if($data['old']['type'] == 'vhost') {
FS 2309                 $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
2310                 $backup_dir = $server_config['backup_dir'];
2311                 $mount_backup = true;
a81238 2312                 if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') {
990ca8 2313                     //* mount backup directory, if necessary
FS 2314                     if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false;
2315
69b1bc 2316                     if($mount_backup){
FS 2317                         $web_backup_dir = $backup_dir.'/web'.$data_old['domain_id'];
2318                         //** do not use rm -rf $web_backup_dir because database(s) may exits
2319                         exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*');
2320                         //* cleanup database
990ca8 2321                         $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?";
FS 2322                         $app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%");
2323                         if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%");
0f89bd 2324
FS 2325                         $app->log('Deleted the web backup files', LOGLEVEL_DEBUG);
69b1bc 2326                     }
FS 2327                 }
2328             }
46c683 2329         }
b1a6a5 2330         if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true);
46c683 2331     }
ac933e 2332
46c683 2333     //* This function is called when a IP on the server is inserted, updated or deleted
b1a6a5 2334     function server_ip($event_name, $data) {
46c683 2335         global $app, $conf;
ac933e 2336
46c683 2337         // load the server configuration options
fb3339 2338         $app->uses('getconf');
J 2339         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 2340
46c683 2341         $app->load('tpl');
ac933e 2342
46c683 2343         $tpl = new tpl();
fb3339 2344         $tpl->newTemplate('apache_ispconfig.conf.master');
8133de 2345         $tpl->setVar('apache_version', $app->system->getapacheversion());
2af58c 2346         $records = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ? AND virtualhost = 'y'", $conf['server_id']);
b1a6a5 2347
a2156e 2348         $records_out= array();
T 2349         if(is_array($records)) {
2350             foreach($records as $rec) {
2351                 if($rec['ip_type'] == 'IPv6') {
2352                     $ip_address = '['.$rec['ip_address'].']';
2353                 } else {
2354                     $ip_address = $rec['ip_address'];
2355                 }
b1a6a5 2356                 $ports = explode(',', $rec['virtualhost_port']);
a2156e 2357                 if(is_array($ports)) {
T 2358                     foreach($ports as $port) {
2359                         $port = intval($port);
2360                         if($port > 0 && $port < 65536 && $ip_address != '') {
2361                             $records_out[] = array('ip_address' => $ip_address, 'port' => $port);
2362                         }
2363                     }
2364                 }
2365             }
2366         }
b1a6a5 2367
MC 2368
a2156e 2369         if(count($records_out) > 0) {
b1a6a5 2370             $tpl->setLoop('ip_adresses', $records_out);
46c683 2371         }
ac933e 2372
fb3339 2373         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf');
b1a6a5 2374         $app->system->file_put_contents($vhost_file, $tpl->grab());
MC 2375         $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 2376         unset($tpl);
ac933e 2377
46c683 2378     }
b1a6a5 2379
524077 2380     //* Create or update the .htaccess folder protection
b1a6a5 2381     function web_folder_user($event_name, $data) {
524077 2382         global $app, $conf;
c69439 2383
524077 2384         $app->uses('system');
b1a6a5 2385
524077 2386         if($event_name == 'web_folder_user_delete') {
T 2387             $folder_id = $data['old']['web_folder_id'];
2388         } else {
2389             $folder_id = $data['new']['web_folder_id'];
2390         }
b1a6a5 2391
2af58c 2392         $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id);
MC 2393         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']);
b1a6a5 2394
524077 2395         if(!is_array($folder) or !is_array($website)) {
b1a6a5 2396             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
524077 2397             return false;
T 2398         }
b1a6a5 2399
MC 2400         $web_folder = 'web';
511ba5 2401         if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
b1a6a5 2402
524077 2403         //* Get the folder path.
b1a6a5 2404         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2405         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
6fb93d 2406         $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
b1a6a5 2407         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2408
524077 2409         //* Check if the resulting path is inside the docroot
b1a6a5 2410         if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) {
MC 2411             $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
524077 2412             return false;
T 2413         }
b1a6a5 2414
524077 2415         //* Create the folder path, if it does not exist
8cf78b 2416         if(!is_dir($folder_path)) {
dbae22 2417             $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']);
8cf78b 2418         }
b1a6a5 2419
524077 2420         //* Create empty .htpasswd file, if it does not exist
T 2421         if(!is_file($folder_path.'.htpasswd')) {
4bd960 2422             $app->system->touch($folder_path.'.htpasswd');
51910d 2423             $app->system->chmod($folder_path.'.htpasswd', 0751);
b1a6a5 2424             $app->system->chown($folder_path.'.htpasswd', $website['system_user']);
MC 2425             $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']);
2426             $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
524077 2427         }
b1a6a5 2428
8ab3cd 2429         if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
b1a6a5 2430             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2431             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
c69439 2432         }
b1a6a5 2433
524077 2434         //* Add or remove the user from .htpasswd file
T 2435         if($event_name == 'web_folder_user_delete') {
b1a6a5 2436             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2437             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
524077 2438         } else {
c69439 2439             if($data['new']['active'] == 'y') {
b1a6a5 2440                 $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1);
MC 2441                 $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG);
c69439 2442             }
524077 2443         }
b1a6a5 2444
MC 2445
524077 2446         //* Create the .htaccess file
8ab3cd 2447         //if(!is_file($folder_path.'.htaccess')) {
b1a6a5 2448         $begin_marker = '### ISPConfig folder protection begin ###';
MC 2449         $end_marker = "### ISPConfig folder protection end ###\n\n";
2450         $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
2451
2452         if(file_exists($folder_path.'.htaccess')) {
2453             $old_content = $app->system->file_get_contents($folder_path.'.htaccess');
2454
2455             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2456                 $ht_file = str_replace($matches[0], $ht_file, $old_content);
2457             } else {
2458                 $ht_file .= $old_content;
2459             }
2460         }
2461         unset($old_content);
2462
2463         $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
51910d 2464         $app->system->chmod($folder_path.'.htaccess', 0751);
b1a6a5 2465         $app->system->chown($folder_path.'.htaccess', $website['system_user']);
MC 2466         $app->system->chgrp($folder_path.'.htaccess', $website['system_group']);
2467         $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
8ab3cd 2468         //}
b1a6a5 2469
524077 2470     }
b1a6a5 2471
524077 2472     //* Remove .htaccess and .htpasswd file, when folder protection is removed
b1a6a5 2473     function web_folder_delete($event_name, $data) {
524077 2474         global $app, $conf;
b1a6a5 2475
524077 2476         $folder_id = $data['old']['web_folder_id'];
b1a6a5 2477
8ab3cd 2478         $folder = $data['old'];
2af58c 2479         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']);
b1a6a5 2480
524077 2481         if(!is_array($folder) or !is_array($website)) {
b1a6a5 2482             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
524077 2483             return false;
T 2484         }
b1a6a5 2485
MC 2486         $web_folder = 'web';
511ba5 2487         if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
b1a6a5 2488
524077 2489         //* Get the folder path.
b1a6a5 2490         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2491         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
6fb93d 2492         $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
b1a6a5 2493         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2494
524077 2495         //* Check if the resulting path is inside the docroot
b1a6a5 2496         if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2497             $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG);
524077 2498             return false;
T 2499         }
b1a6a5 2500
524077 2501         //* Remove .htpasswd file
T 2502         if(is_file($folder_path.'.htpasswd')) {
c77103 2503             $app->system->unlink($folder_path.'.htpasswd');
b1a6a5 2504             $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
524077 2505         }
b1a6a5 2506
524077 2507         //* Remove .htaccess file
T 2508         if(is_file($folder_path.'.htaccess')) {
b1a6a5 2509             $begin_marker = '### ISPConfig folder protection begin ###';
MC 2510             $end_marker = "### ISPConfig folder protection end ###\n\n";
2511
2512             $ht_file = $app->system->file_get_contents($folder_path.'.htaccess');
2513
2514             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2515                 $ht_file = str_replace($matches[0], '', $ht_file);
2516             } else {
2517                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2518             }
2519
2520             if(trim($ht_file) == '') {
2521                 $app->system->unlink($folder_path.'.htaccess');
2522                 $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
2523             } else {
2524                 $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
2525                 $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
2526             }
524077 2527         }
2023a7 2528     }
b1a6a5 2529
2023a7 2530     //* Update folder protection, when path has been changed
b1a6a5 2531     function web_folder_update($event_name, $data) {
2023a7 2532         global $app, $conf;
b1a6a5 2533
2af58c 2534         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
b1a6a5 2535
2023a7 2536         if(!is_array($website)) {
b1a6a5 2537             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
2023a7 2538             return false;
T 2539         }
b1a6a5 2540
MC 2541         $web_folder = 'web';
511ba5 2542         if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
b1a6a5 2543
2023a7 2544         //* Get the folder path.
b1a6a5 2545         if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1);
MC 2546         if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1);
6fb93d 2547         $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']);
b1a6a5 2548         if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/';
MC 2549
2550         if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1);
2551         if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1);
6fb93d 2552         $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']);
b1a6a5 2553         if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/';
MC 2554
2023a7 2555         //* Check if the resulting path is inside the docroot
b1a6a5 2556         if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) {
MC 2557             $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
2023a7 2558             return false;
T 2559         }
b1a6a5 2560         if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) {
MC 2561             $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
2023a7 2562             return false;
T 2563         }
b1a6a5 2564
2023a7 2565         //* Check if the resulting path is inside the docroot
b1a6a5 2566         if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2567             $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
2023a7 2568             return false;
T 2569         }
b1a6a5 2570         if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2571             $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
2023a7 2572             return false;
T 2573         }
b1a6a5 2574
2023a7 2575         //* Create the folder path, if it does not exist
c77103 2576         if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path);
b1a6a5 2577
MC 2578         $begin_marker = '### ISPConfig folder protection begin ###';
2579         $end_marker = "### ISPConfig folder protection end ###\n\n";
2580
2023a7 2581         if($data['old']['path'] != $data['new']['path']) {
T 2582
b1a6a5 2583
2023a7 2584             //* move .htpasswd file
T 2585             if(is_file($old_folder_path.'.htpasswd')) {
b1a6a5 2586                 $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd');
MC 2587                 $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
2023a7 2588             }
b1a6a5 2589
8ab3cd 2590             //* delete old .htaccess file
2023a7 2591             if(is_file($old_folder_path.'.htaccess')) {
b1a6a5 2592                 $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess');
MC 2593
2594                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2595                     $ht_file = str_replace($matches[0], '', $ht_file);
2596                 } else {
2597                     $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2598                 }
2599
2600                 if(trim($ht_file) == '') {
2601                     $app->system->unlink($old_folder_path.'.htaccess');
2602                     $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2603                 } else {
2604                     $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file);
2605                     $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2606                 }
2023a7 2607             }
b1a6a5 2608
2023a7 2609         }
b1a6a5 2610
2023a7 2611         //* Create the .htaccess file
8ab3cd 2612         if($data['new']['active'] == 'y') {
b1a6a5 2613             $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
MC 2614
2615             if(file_exists($new_folder_path.'.htaccess')) {
2616                 $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess');
2617
2618                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2619                     $ht_file = str_replace($matches[0], $ht_file, $old_content);
2620                 } else {
2621                     $ht_file .= $old_content;
2622                 }
2623             }
2624
2625             $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
51910d 2626             $app->system->chmod($new_folder_path.'.htaccess', 0751);
b1a6a5 2627             $app->system->chown($new_folder_path.'.htaccess', $website['system_user']);
MC 2628             $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']);
2629             $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
8433d0 2630             
TB 2631             //* Create empty .htpasswd file, if it does not exist
2632             if(!is_file($folder_path.'.htpasswd')) {
2633                 $app->system->touch($new_folder_path.'.htpasswd');
51910d 2634                 $app->system->chmod($new_folder_path.'.htpasswd', 0751);
8433d0 2635                 $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']);
TB 2636                 $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']);
2637                 $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
2638             }
2023a7 2639         }
b1a6a5 2640
2023a7 2641         //* Remove .htaccess file
T 2642         if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
b1a6a5 2643             $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess');
MC 2644
2645             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2646                 $ht_file = str_replace($matches[0], '', $ht_file);
2647             } else {
2648                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2649             }
2650
2651             if(trim($ht_file) == '') {
2652                 $app->system->unlink($new_folder_path.'.htaccess');
2653                 $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2654             } else {
2655                 $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
2656                 $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2657             }
2023a7 2658         }
b1a6a5 2659
MC 2660
524077 2661     }
b1a6a5 2662
MC 2663     public function ftp_user_delete($event_name, $data) {
26c0fc 2664         global $app, $conf;
b1a6a5 2665
26c0fc 2666         $ftpquota_file = $data['old']['dir'].'/.ftpquota';
c77103 2667         if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file);
b1a6a5 2668
26c0fc 2669     }
b1a6a5 2670
MC 2671
ac933e 2672
V 2673     /**
2674      * This function is called when a Webdav-User is inserted, updated or deleted.
2675      *
2676      * @author Oliver Vogel
2677      * @param string $event_name
2678      * @param array $data
2679      */
b1a6a5 2680     public function webdav($event_name, $data) {
ac933e 2681         global $app, $conf;
b1a6a5 2682
52a04e 2683         /*
T 2684          * load the server configuration options
2685         */
fb3339 2686         $app->uses('getconf');
J 2687         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 2688
V 2689         if (($event_name == 'webdav_user_insert') || ($event_name == 'webdav_user_update')) {
2690
2691             /*
2692              * Get additional informations
2693             */
2af58c 2694             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
ac933e 2695             $documentRoot = $sitedata['document_root'];
V 2696             $domain = $sitedata['domain'];
ca14fe 2697             $user = $sitedata['system_user'];
V 2698             $group = $sitedata['system_group'];
b67344 2699             $webdav_user_dir = $documentRoot . '/webdav/' . $data['new']['dir'];
ac933e 2700
V 2701             /* Check if this is a chrooted setup */
2702             if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2703                 $apache_chrooted = true;
b1a6a5 2704                 $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
ac933e 2705             } else {
V 2706                 $apache_chrooted = false;
2707             }
b1a6a5 2708
b67344 2709             //* We dont want to have relative paths here
b1a6a5 2710             if(stristr($webdav_user_dir, '..')  || stristr($webdav_user_dir, './')) {
MC 2711                 $app->log('Folder path '.$webdav_user_dir.' contains ./ or .. '.$documentRoot, LOGLEVEL_WARN);
b67344 2712                 return false;
T 2713             }
b1a6a5 2714
b67344 2715             //* Check if the resulting path exists if yes, if it is inside the docroot
b1a6a5 2716             if(is_dir($webdav_user_dir) && substr(realpath($webdav_user_dir), 0, strlen($documentRoot)) != $documentRoot) {
MC 2717                 $app->log('Folder path '.$webdav_user_dir.' is outside of docroot '.$documentRoot, LOGLEVEL_WARN);
b67344 2718                 return false;
T 2719             }
ac933e 2720
V 2721             /*
2722              * First the webdav-root - folder has to exist
2723             */
b67344 2724             if(!is_dir($webdav_user_dir)) {
b1a6a5 2725                 $app->log('Webdav User directory '.$webdav_user_dir.' does not exist. Creating it now.', LOGLEVEL_DEBUG);
c77103 2726                 $app->system->mkdirpath($webdav_user_dir);
ac933e 2727             }
V 2728
2729             /*
ca14fe 2730              * The webdav - Root needs the group/user as owner and the apache as read and write
ac933e 2731             */
c77103 2732             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($documentRoot . '/webdav/'));
T 2733             //$this->_exec('chmod 770 ' . escapeshellcmd($documentRoot . '/webdav/'));
b1a6a5 2734             $app->system->chown($documentRoot . '/webdav', $user);
MC 2735             $app->system->chgrp($documentRoot . '/webdav', $group);
2736             $app->system->chmod($documentRoot . '/webdav', 0770);
ac933e 2737
V 2738             /*
ca14fe 2739              * The webdav folder (not the webdav-root!) needs the same (not in ONE step, because the
V 2740              * pwd-files are owned by root)
ac933e 2741             */
c77103 2742             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($webdav_user_dir.' -R'));
T 2743             //$this->_exec('chmod 770 ' . escapeshellcmd($webdav_user_dir.' -R'));
b1a6a5 2744             $app->system->chown($webdav_user_dir, $user);
MC 2745             $app->system->chgrp($webdav_user_dir, $group);
2746             $app->system->chmod($webdav_user_dir, 0770);
ca14fe 2747
V 2748             /*
2749              * if the user is active, we have to write/update the password - file
2750              * if the user is inactive, we have to inactivate the user by removing the user from the file
2751             */
2752             if ($data['new']['active'] == 'y') {
b67344 2753                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
ca14fe 2754             }
V 2755             else {
2756                 /* empty pwd removes the user! */
b67344 2757                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
ca14fe 2758             }
ac933e 2759
V 2760             /*
2761              * Next step, patch the vhost - file
2762             */
fb3339 2763             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
ac933e 2764             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
ca14fe 2765
ac933e 2766             /*
V 2767              * Last, restart apache
2768             */
2769             if($apache_chrooted) {
b1a6a5 2770                 $app->services->restartServiceDelayed('httpd', 'restart');
ac933e 2771             } else {
V 2772                 // request a httpd reload when all records have been processed
b1a6a5 2773                 $app->services->restartServiceDelayed('httpd', 'reload');
ac933e 2774             }
V 2775
2776         }
2777
2778         if ($event_name == 'webdav_user_delete') {
2779             /*
2780              * Get additional informations
2781             */
2af58c 2782             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
ac933e 2783             $documentRoot = $sitedata['document_root'];
52a04e 2784             $domain = $sitedata['domain'];
ac933e 2785
V 2786             /*
2787              * We dont't want to destroy any (transfer)-Data. So we do NOT delete any dir.
2788              * So the only thing, we have to do, is to delete the user from the password-file
ca14fe 2789             */
ac933e 2790             $this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['old']['dir'] . '.htdigest', $data['old']['username'], $data['old']['dir'], '');
b1a6a5 2791
52a04e 2792             /*
T 2793              * Next step, patch the vhost - file
2794             */
fb3339 2795             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
52a04e 2796             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
b1a6a5 2797
52a04e 2798             /*
T 2799              * Last, restart apache
2800             */
2801             if($apache_chrooted) {
b1a6a5 2802                 $app->services->restartServiceDelayed('httpd', 'restart');
52a04e 2803             } else {
T 2804                 // request a httpd reload when all records have been processed
b1a6a5 2805                 $app->services->restartServiceDelayed('httpd', 'reload');
52a04e 2806             }
ac933e 2807         }
V 2808     }
2809
2810
2811     /**
2812      * This function writes the htdigest - files used by webdav and digest
ca14fe 2813      * more info: see http://riceball.com/d/node/424
ac933e 2814      * @author Oliver Vogel
V 2815      * @param string $filename The name of the digest-file
2816      * @param string $username The name of the webdav-user
2817      * @param string $authname The name of the realm
ca14fe 2818      * @param string $pwd      The password-hash of the user
ac933e 2819      */
ca14fe 2820     private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) {
4bd960 2821         global $app;
b1a6a5 2822
ac933e 2823         $changed = false;
c77103 2824         if(is_file($filename) && !is_link($filename)) {
0ff3f1 2825             $in = fopen($filename, 'r');
T 2826             $output = '';
2827             /*
2828             * read line by line and search for the username and authname
2829             */
2830             while (preg_match("/:/", $line = fgets($in))) {
2831                 $line = rtrim($line);
2832                 $tmp = explode(':', $line);
2833                 if ($tmp[0] == $username && $tmp[1] == $authname) {
2834                     /*
2835                     * found the user. delete or change it?
2836                     */
2837                     if ($pwdhash != '') {
2838                         $output .= $tmp[0] . ':' . $tmp[1] . ':' . $pwdhash . "\n";
b1a6a5 2839                     }
0ff3f1 2840                     $changed = true;
T 2841                 }
2842                 else {
2843                     $output .= $line . "\n";
2844                 }
ac933e 2845             }
0ff3f1 2846             fclose($in);
ac933e 2847         }
V 2848         /*
2849          * if we didn't change anything, we have to add the new user at the end of the file
2850         */
2851         if (!$changed) {
f17dab 2852             $output .= $username . ':' . $authname . ':' . $pwdhash . "\n";
ac933e 2853         }
b1a6a5 2854
ac933e 2855
V 2856         /*
2857          * Now lets write the new file
2858         */
52a04e 2859         if(trim($output) == '') {
c77103 2860             $app->system->unlink($filename);
52a04e 2861         } else {
c77103 2862             $app->system->file_put_contents($filename, $output);
52a04e 2863         }
ac933e 2864     }
V 2865
2866     /**
2867      * This function patches the vhost-file and adds all webdav - user.
2868      * This function is written, because the creation of the vhost - file is sophisticated and
2869      * i don't want to make it more "heavy" by also adding this code too...
2870      * @author Oliver Vogel
2871      * @param string $fileName The Name of the .vhost-File (path included)
2872      * @param string $webdavRoot The root of the webdav-folder
2873      */
2874     private function _patchVhostWebdav($fileName, $webdavRoot) {
c77103 2875         global $app;
ac933e 2876         $in = fopen($fileName, 'r');
V 2877         $output = '';
2878         $inWebdavSection = false;
2879
2880         /*
2881          * read line by line and search for the username and authname
2882         */
2883         while ($line = fgets($in)) {
2884             /*
2885              *  is the "replace-comment" found...
2886             */
2887             if (trim($line) == '# WEBDAV BEGIN') {
2888                 /*
2889                  * The begin of the webdav - section is found, so ignore all lines til the end  is found
2890                 */
2891                 $inWebdavSection = true;
2892
2893                 $output .= "      # WEBDAV BEGIN\n";
2894
2895                 /*
2896                  * add all the webdav-dirs to the webdav-section
2897                 */
fb3a98 2898                 $files = @scandir($webdavRoot);
T 2899                 if(is_array($files)) {
b1a6a5 2900                     foreach($files as $file) {
MC 2901                         if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) {
2902                             /*
ac933e 2903                          * found a htdigest - file, so add it to webdav
V 2904                         */
b1a6a5 2905                             $fn = substr($file, 0, strlen($file) - strlen('.htdigest'));
MC 2906                             $output .= "\n";
2907                             // $output .= "      Alias /" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
2908                             // $output .= "      <Location /" . $fn . ">\n";
2909                             $output .= "      Alias /webdav/" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
2910                             $output .= "      <Location /webdav/" . $fn . ">\n";
2911                             $output .= "        DAV On\n";
2912                             $output .= '        BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On'."\n";
2913                             $output .= "        AuthType Digest\n";
2914                             $output .= "        AuthName \"" . $fn . "\"\n";
2915                             $output .= "        AuthUserFile " . $webdavRoot . '/' . $file . "\n";
2916                             $output .= "        Require valid-user \n";
2917                             $output .= "        Options +Indexes \n";
2918                             $output .= "        Order allow,deny \n";
2919                             $output .= "        Allow from all \n";
2920                             $output .= "      </Location> \n";
2921                         }
ac933e 2922                     }
fb3a98 2923                 }
ac933e 2924             }
V 2925             /*
2926              *  is the "replace-comment-end" found...
2927             */
2928             if (trim($line) == '# WEBDAV END') {
2929                 /*
2930                  * The end of the webdav - section is found, so stop ignoring
2931                 */
2932                 $inWebdavSection = false;
2933             }
2934
2935             /*
2936              * Write the line to the output, if it is not in the section
2937             */
2938             if (!$inWebdavSection) {
2939                 $output .= $line;
2940             }
2941         }
2942         fclose($in);
2943
2944         /*
2945          * Now lets write the new file
2946         */
c77103 2947         $app->system->file_put_contents($fileName, $output);
ac933e 2948
V 2949     }
b1a6a5 2950
58c210 2951     //* Update the awstats configuration file
b1a6a5 2952     private function awstats_update ($data, $web_config) {
58c210 2953         global $app;
b1a6a5 2954
MC 2955         $web_folder = $data['new']['web_folder'];
2956         if($data['new']['type'] == 'vhost') $web_folder = 'web';
2a6eac 2957         $awstats_conf_dir = $web_config['awstats_conf_dir'];
b1a6a5 2958
6fb93d 2959         if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats");
fb3339 2960         if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) {
J 2961             if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2962                 $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
58c210 2963             }
b1a6a5 2964
58c210 2965             $content = '';
e6abfe 2966             if (is_file($awstats_conf_dir."/awstats.conf")) {
CS 2967                 $include_file = $awstats_conf_dir."/awstats.conf";
2968             } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) {
2969                 $include_file = $awstats_conf_dir."/awstats.model.conf";
2970             }
de6d2e 2971             $content .= "Include \"".$include_file."\"\n";
fb3339 2972             $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n";
J 2973             $content .= "SiteDomain=\"".$data['new']['domain']."\"\n";
2974             $content .= "HostAliases=\"www.".$data['new']['domain']."  localhost 127.0.0.1\"\n";
b1a6a5 2975
9aaf97 2976             if (isset($include_file)) {
CS 2977                 $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content);
2978                 $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG);
2979             } else {
2980                 $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN);
2981             }
58c210 2982         }
b1a6a5 2983
6fb93d 2984         if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html");
a464e1 2985         if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) {
b1a6a5 2986             $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
a464e1 2987         } else {
b1a6a5 2988             $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
a464e1 2989         }
58c210 2990     }
b1a6a5 2991
58c210 2992     //* Delete the awstats configuration file
b1a6a5 2993     private function awstats_delete ($data, $web_config) {
58c210 2994         global $app;
b1a6a5 2995
58c210 2996         $awstats_conf_dir = $web_config['awstats_conf_dir'];
b1a6a5 2997
fb3339 2998         if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2999             $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
b1a6a5 3000             $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG);
58c210 3001         }
T 3002     }
b1a6a5 3003
c59632 3004     private function hhvm_update($data, $web_config) {
MC 3005         global $app, $conf;
3006         
3007         if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_starter.master')) {
3008             $content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_starter.master');
3009         } else {
3010             $content = file_get_contents($conf['rootpath'] . '/conf/hhvm_starter.master');
3011         }
cab08c 3012         if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_monit.master')) {
MC 3013             $monit_content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_monit.master');
3014         } else {
3015             $monit_content = file_get_contents($conf['rootpath'] . '/conf/hhvm_monit.master');
3016         }
c59632 3017         
d22277 3018         if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || (isset($data['old']['custom_php_ini']) && $data['new']['custom_php_ini'] != $data['old']['custom_php_ini'])) {
d5f2d5 3019         
MC 3020             // Custom php.ini settings
3021             $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
3022             if(intval($data['new']['directive_snippets_id']) > 0){
d22277 3023                 $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
d5f2d5 3024                 if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
MC 3025                     $required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
3026                     if(is_array($required_php_snippets) && !empty($required_php_snippets)){
3027                         foreach($required_php_snippets as $required_php_snippet){
3028                             $required_php_snippet = intval($required_php_snippet);
3029                             if($required_php_snippet > 0){
d22277 3030                                 $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
d5f2d5 3031                                 $php_snippet['snippet'] = trim($php_snippet['snippet']);
MC 3032                                 if($php_snippet['snippet'] != ''){
3033                                     $custom_php_ini_settings .= "\n".$php_snippet['snippet'];
3034                                 }
3035                             }
3036                         }
3037                     }
3038                 }
3039             }
3040             if($custom_php_ini_settings != ''){
3041                 // Make sure we only have Unix linebreaks
3042                 $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
3043                 $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
3044                 file_put_contents('/etc/hhvm/'.$data['new']['system_user'].'.ini', $custom_php_ini_settings);
3045             } else {
d22277 3046                 if($data['old']['system_user'] != '' && is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
d5f2d5 3047             }
MC 3048             
1c6da3 3049             $content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $content);
c59632 3050             file_put_contents('/etc/init.d/hhvm_' . $data['new']['system_user'], $content);
MC 3051             exec('chmod +x /etc/init.d/hhvm_' . $data['new']['system_user'] . ' >/dev/null 2>&1');
3052             exec('/usr/sbin/update-rc.d hhvm_' . $data['new']['system_user'] . ' defaults >/dev/null 2>&1');
02e7ea 3053             exec('/etc/init.d/hhvm_' . $data['new']['system_user'] . ' restart >/dev/null 2>&1');
cab08c 3054             
02e7ea 3055             if(is_dir('/etc/monit/conf.d')){
MC 3056                 $monit_content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $monit_content);
3057                 file_put_contents('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'], $monit_content);
3058                 if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])) unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']);
3059                 exec('/etc/init.d/monit restart >/dev/null 2>&1');
3060             }
cab08c 3061             
c59632 3062          } elseif($data['new']['php'] != 'hhvm' && $data['old']['php'] == 'hhvm') {
d22277 3063             if($data['old']['system_user'] != ''){
MB 3064                 exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1');
3065                 exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1');
3066                 unlink('/etc/init.d/hhvm_' . $data['old']['system_user']);
3067                 if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
3068             }
cab08c 3069             
02e7ea 3070             if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']) || is_file('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'])){
MC 3071                 if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])){
3072                     unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']);
3073                 }
3074                 if(is_file('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'])){
3075                     unlink('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user']);
3076                 }
cab08c 3077                 exec('/etc/init.d/monit restart >/dev/null 2>&1');
MC 3078             }
c59632 3079         }
MC 3080     }
3081
274362 3082     //* Update the PHP-FPM pool configuration file
b1a6a5 3083     private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) {
274362 3084         global $app, $conf;
ab79c2 3085         $pool_dir = trim($pool_dir);
274362 3086         //$reload = false;
b1a6a5 3087
62e4b3 3088         if($data['new']['php'] == 'php-fpm'){
F 3089             if(trim($data['new']['fastcgi_php_version']) != ''){
3090                 $default_php_fpm = false;
3091                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
b1a6a5 3092                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 3093             } else {
F 3094                 $default_php_fpm = true;
3095             }
274362 3096         } else {
62e4b3 3097             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
F 3098                 $default_php_fpm = false;
3099                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
b1a6a5 3100                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 3101             } else {
F 3102                 $default_php_fpm = true;
3103             }
274362 3104         }
b1a6a5 3105
274362 3106         $app->uses("getconf");
F 3107         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
b1a6a5 3108
274362 3109         if($data['new']['php'] != 'php-fpm'){
F 3110             if(@is_file($pool_dir.$pool_name.'.conf')){
c77103 3111                 $app->system->unlink($pool_dir.$pool_name.'.conf');
274362 3112                 //$reload = true;
F 3113             }
3114             if($data['old']['php'] == 'php-fpm'){
3115                 if(!$default_php_fpm){
b1a6a5 3116                     $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 3117                 } else {
b1a6a5 3118                     $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 3119                 }
F 3120             }
3121             //if($reload == true) $app->services->restartService('php-fpm','reload');
3122             return;
3123         }
b1a6a5 3124
274362 3125         $app->load('tpl');
F 3126         $tpl = new tpl();
3127         $tpl->newTemplate('php_fpm_pool.conf.master');
8133de 3128         $tpl->setVar('apache_version', $app->system->getapacheversion());
MC 3129         
c91c7a 3130         $apache_modules = $app->system->getapachemodules();
TB 3131         
6db036 3132         // Use sockets, but not with apache 2.4 on centos (mod_proxy_fcgi) as socket support is buggy in that version
TB 3133         if($data['new']['php_fpm_use_socket'] == 'y' && in_array('fastcgi_module',$apache_modules)){
274362 3134             $use_tcp = 0;
F 3135             $use_socket = 1;
c77103 3136             if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir);
274362 3137         } else {
F 3138             $use_tcp = 1;
3139             $use_socket = 0;
3140         }
3141         $tpl->setVar('use_tcp', $use_tcp);
3142         $tpl->setVar('use_socket', $use_socket);
b1a6a5 3143
274362 3144         $fpm_socket = $socket_dir.$pool_name.'.sock';
F 3145         $tpl->setVar('fpm_socket', $fpm_socket);
b491ad 3146         $tpl->setVar('fpm_listen_mode', '0660');
b1a6a5 3147
274362 3148         $tpl->setVar('fpm_pool', $pool_name);
F 3149         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
3150         $tpl->setVar('fpm_user', $data['new']['system_user']);
3151         $tpl->setVar('fpm_group', $data['new']['system_group']);
d33fd2 3152         $tpl->setVar('fpm_domain', $data['new']['domain']);
dd7ce4 3153         $tpl->setVar('pm', $data['new']['pm']);
274362 3154         $tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
F 3155         $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']);
3156         $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']);
3157         $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']);
dd7ce4 3158         $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']);
F 3159         $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']);
274362 3160         $tpl->setVar('document_root', $data['new']['document_root']);
b1a6a5 3161         $tpl->setVar('security_level', $web_config['security_level']);
f63910 3162         $tpl->setVar('domain', $data['new']['domain']);
274362 3163         $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']);
F 3164         $tpl->setVar('php_open_basedir', $php_open_basedir);
3165         if($php_open_basedir != ''){
3166             $tpl->setVar('enable_php_open_basedir', '');
3167         } else {
3168             $tpl->setVar('enable_php_open_basedir', ';');
3169         }
b1a6a5 3170
274362 3171         // Custom php.ini settings
F 3172         $final_php_ini_settings = array();
3173         $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
b41803 3174         
MC 3175         if(intval($data['new']['directive_snippets_id']) > 0){
3176             $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
3177             if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
3178                 $required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
3179                 if(is_array($required_php_snippets) && !empty($required_php_snippets)){
3180                     foreach($required_php_snippets as $required_php_snippet){
3181                         $required_php_snippet = intval($required_php_snippet);
3182                         if($required_php_snippet > 0){
d22277 3183                             $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
b41803 3184                             $php_snippet['snippet'] = trim($php_snippet['snippet']);
MC 3185                             if($php_snippet['snippet'] != ''){
3186                                 $custom_php_ini_settings .= "\n".$php_snippet['snippet'];
3187                             }
3188                         }
3189                     }
3190                 }
3191             }
3192         }
3193         
9fd930 3194         $custom_session_save_path = false;
274362 3195         if($custom_php_ini_settings != ''){
F 3196             // Make sure we only have Unix linebreaks
3197             $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
3198             $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
3199             $ini_settings = explode("\n", $custom_php_ini_settings);
3200             if(is_array($ini_settings) && !empty($ini_settings)){
3201                 foreach($ini_settings as $ini_setting){
254a4a 3202                     $ini_setting = trim($ini_setting);
b1a6a5 3203                     if(substr($ini_setting, 0, 1) == ';') continue;
MC 3204                     if(substr($ini_setting, 0, 1) == '#') continue;
3205                     if(substr($ini_setting, 0, 2) == '//') continue;
03cc01 3206                     list($key, $value) = explode('=', $ini_setting, 2);
1d6097 3207                     $value = trim($value);
FT 3208                     if($value != ''){
254a4a 3209                         $key = trim($key);
9fd930 3210                         if($key == 'session.save_path') $custom_session_save_path = true;
254a4a 3211                         switch (strtolower($value)) {
b1a6a5 3212                         case '0':
MC 3213                             // PHP-FPM might complain about invalid boolean value if you use 0
3214                             $value = 'off';
3215                         case '1':
3216                         case 'on':
3217                         case 'off':
3218                         case 'true':
3219                         case 'false':
3220                         case 'yes':
3221                         case 'no':
3222                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value);
3223                             break;
3224                         default:
3225                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value);
274362 3226                         }
254a4a 3227                     }
274362 3228                 }
F 3229             }
3230         }
9fd930 3231         
MB 3232         $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n'));
3233         
274362 3234         $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
b1a6a5 3235
MC 3236         $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab());
3237         $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
274362 3238         unset($tpl);
b1a6a5 3239
274362 3240         // delete pool in all other PHP versions
ab79c2 3241         $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir']));
b1a6a5 3242         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
274362 3243         if($default_pool_dir != $pool_dir){
F 3244             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
b1a6a5 3245                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 3246                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
3247                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 3248             }
F 3249         }
2af58c 3250         $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ?", $conf["server_id"]);
274362 3251         if(is_array($php_versions) && !empty($php_versions)){
F 3252             foreach($php_versions as $php_version){
ab79c2 3253                 $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']);
b1a6a5 3254                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
274362 3255                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
F 3256                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 3257                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
b1a6a5 3258                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 3259                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
274362 3260                     }
F 3261                 }
3262             }
3263         }
3264         // Reload current PHP-FPM after all others
3265         sleep(1);
3266         if(!$default_php_fpm){
b1a6a5 3267             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 3268         } else {
b1a6a5 3269             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 3270         }
b1a6a5 3271
274362 3272         //$reload = true;
F 3273
3274         //if($reload == true) $app->services->restartService('php-fpm','reload');
3275     }
b1a6a5 3276
274362 3277     //* Delete the PHP-FPM pool configuration file
b1a6a5 3278     private function php_fpm_pool_delete ($data, $web_config) {
274362 3279         global $app, $conf;
b1a6a5 3280
62e4b3 3281         if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
274362 3282             $default_php_fpm = false;
F 3283             list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
b1a6a5 3284             if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
274362 3285         } else {
F 3286             $default_php_fpm = true;
3287         }
b1a6a5 3288
274362 3289         if($default_php_fpm){
F 3290             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
3291         } else {
3292             $pool_dir = $custom_php_fpm_pool_dir;
3293         }
ab79c2 3294         $pool_dir = trim($pool_dir);
b1a6a5 3295
MC 3296         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
274362 3297         $pool_name = 'web'.$data['old']['domain_id'];
b1a6a5 3298
274362 3299         if ( @is_file($pool_dir.$pool_name.'.conf') ) {
c77103 3300             $app->system->unlink($pool_dir.$pool_name.'.conf');
b1a6a5 3301             $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 3302
274362 3303             //$app->services->restartService('php-fpm','reload');
F 3304         }
b1a6a5 3305
274362 3306         // delete pool in all other PHP versions
ab79c2 3307         $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir']));
b1a6a5 3308         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
274362 3309         if($default_pool_dir != $pool_dir){
F 3310             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
b1a6a5 3311                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 3312                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
3313                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 3314             }
b1a6a5 3315         }
2af58c 3316         $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ?", $data['old']['server_id']);
274362 3317         if(is_array($php_versions) && !empty($php_versions)){
F 3318             foreach($php_versions as $php_version){
ab79c2 3319                 $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']);
b1a6a5 3320                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
274362 3321                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
F 3322                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 3323                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
b1a6a5 3324                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 3325                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
274362 3326                     }
F 3327                 }
3328             }
3329         }
b1a6a5 3330
274362 3331         // Reload current PHP-FPM after all others
F 3332         sleep(1);
3333         if(!$default_php_fpm){
b1a6a5 3334             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 3335         } else {
b1a6a5 3336             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 3337         }
F 3338     }
b1a6a5 3339
MC 3340     function client_delete($event_name, $data) {
1ca823 3341         global $app, $conf;
b1a6a5 3342
1ca823 3343         $app->uses("getconf");
T 3344         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
b1a6a5 3345
1ca823 3346         $client_id = intval($data['old']['client_id']);
T 3347         if($client_id > 0) {
b1a6a5 3348
1ca823 3349             $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id;
b1a6a5 3350             if(is_dir($client_dir) && !stristr($client_dir, '..')) {
72695f 3351                 // remove symlinks from $client_dir
b1a6a5 3352                 $files = array_diff(scandir($client_dir), array('.', '..'));
72695f 3353                 if(is_array($files) && !empty($files)){
T 3354                     foreach($files as $file){
3355                         if(is_link($client_dir.'/'.$file)){
3356                             unlink($client_dir.'/'.$file);
b1a6a5 3357                             $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG);
72695f 3358                         }
T 3359                     }
3360                 }
b1a6a5 3361
1ca823 3362                 @rmdir($client_dir);
b1a6a5 3363                 $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG);
1ca823 3364             }
b1a6a5 3365
615a0a 3366             if($app->system->is_group('client'.$client_id)){
T 3367                 $this->_exec('groupdel client'.$client_id);
b1a6a5 3368                 $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG);
615a0a 3369             }
1ca823 3370         }
b1a6a5 3371
1ca823 3372     }
ac933e 3373
1c40af 3374     //* Wrapper for exec function for easier debugging
T 3375     private function _exec($command) {
3376         global $app;
551d9a 3377         $out = array();
MB 3378         $ret = 0;
b1a6a5 3379         $app->log('exec: '.$command, LOGLEVEL_DEBUG);
551d9a 3380         exec($command, $out, $ret);
MB 3381         if($ret != 0) return false;
3382         else return true;
1c40af 3383     }
7ed741 3384
b1a6a5 3385     private function _checkTcp ($host, $port) {
MC 3386
3387         $fp = @fsockopen($host, $port, $errno, $errstr, 2);
7ed741 3388
T 3389         if ($fp) {
3390             fclose($fp);
3391             return true;
3392         } else {
3393             return false;
3394         }
3395     }
ac933e 3396
552178 3397     public function create_relative_link($f, $t) {
bfcdef 3398         global $app;
b1a6a5 3399
552178 3400         // $from already exists
M 3401         $from = realpath($f);
3402
3403         // realpath requires the traced file to exist - so, lets touch it first, then remove
c77103 3404         @$app->system->unlink($t); touch($t);
552178 3405         $to = realpath($t);
c77103 3406         @$app->system->unlink($t);
552178 3407
M 3408         // Remove from the left side matching path elements from $from and $to
3409         // and get path elements counts
3410         $a1 = explode('/', $from); $a2 = explode('/', $to);
3411         for ($c = 0; $a1[$c] == $a2[$c]; $c++) {
3412             unset($a1[$c]); unset($a2[$c]);
3413         }
3414         $cfrom = implode('/', $a1);
3415
3416         // Check if a path is fully a subpath of another - no way to create symlink in the case
3417         if (count($a1) == 0 || count($a2) == 0) return false;
3418
3419         // Add ($cnt_to-1) number of "../" elements to left side of $cfrom
3420         for ($c = 0; $c < (count($a2)-1); $c++) { $cfrom = '../'.$cfrom; }
3421
3422         return symlink($cfrom, $to);
3423     }
46c683 3424
b1a6a5 3425     private function _rewrite_quote($string) {
MC 3426         return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string);
3427     }
3428
3429     private function _is_url($string) {
3430         return preg_match('/^(f|ht)tp(s)?:\/\//i', $string);
3431     }
3432
bfcdef 3433     private function get_seo_redirects($web, $prefix = ''){
T 3434         $seo_redirects = array();
b1a6a5 3435
bfcdef 3436         if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*';
b1a6a5 3437
bfcdef 3438         if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){
T 3439             if($web['seo_redirect'] == 'non_www_to_www'){
3440                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
3441                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
3442                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
3443             }
3444             if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){
3445                 // ^(example\.com|(?!\bwww\b)\.example\.com)$
3446                 // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$
3447                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))';
3448                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
3449                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
3450             }
3451             if($web['seo_redirect'] == '*_to_www_domain_tld'){
3452                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
3453                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
3454                 $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
3455             }
3456         }
3457         if($web['seo_redirect'] == 'www_to_non_www'){
3458             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
3459             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
3460             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
3461         }
3462         if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){
3463             // ^(.+)\.example\.com$
3464             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '(.+)\.'.str_replace('.', '\.', $web['domain']);
3465             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
3466             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
3467         }
3468         if($web['seo_redirect'] == '*_to_domain_tld'){
3469             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
3470             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
3471             $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
3472         }
3473         return $seo_redirects;
3474     }
b1a6a5 3475
46c683 3476 } // end class
T 3477
c09f04 3478 ?>