Marius Cramer
2015-08-06 37b29231e47a0c4458dc1c15d98588f16f07e1e2
commit | author | age
146783 1 <?php
MC 2
3 /*
4 Copyright (c) 2007 - 2012, Till Brehm, projektfarm Gmbh
5 All rights reserved.
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 nginx_plugin {
32
33     var $plugin_name = 'nginx_plugin';
34     var $class_name = 'nginx_plugin';
35
36     // private variables
37     var $action = '';
38     var $ssl_certificate_changed = false;
39
40     //* This function is called during ispconfig installation to determine
41     //  if a symlink shall be created for this plugin.
42     function onInstall() {
43         global $conf;
44
45         if($conf['services']['web'] == true && !@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) {
46             return true;
47         } else {
48             return false;
49         }
50
51     }
52
53
54     /*
55          This function is called when the plugin is loaded
56     */
57
58     function onLoad() {
59         global $app;
60
61         /*
62         Register for the events
63         */
7fe908 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');
146783 67
7fe908 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');
146783 71
7fe908 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');
146783 75
MC 76         /*
77         $app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav');
78         $app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav');
79         $app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav');
80         */
7fe908 81
MC 82         $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete');
83
84         $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user');
85         $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user');
86         $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user');
87
88         $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update');
89         $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete');
146783 90     }
MC 91
92     // Handle the creation of SSL certificates
7fe908 93     function ssl($event_name, $data) {
146783 94         global $app, $conf;
7fe908 95
146783 96         $app->uses('system');
MC 97
98         // load the server configuration options
99         $app->uses('getconf');
100         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
101         if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf'))
7fe908 102             $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR);
MC 103
146783 104         //* Only vhosts can have a ssl cert
511ba5 105         if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return;
146783 106
MC 107         // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
108         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
7fe908 109
146783 110         $ssl_dir = $data['new']['document_root'].'/ssl';
MC 111         $domain = $data['new']['ssl_domain'];
112         $key_file = $ssl_dir.'/'.$domain.'.key.org';
113         $key_file2 = $ssl_dir.'/'.$domain.'.key';
114         $csr_file = $ssl_dir.'/'.$domain.'.csr';
115         $crt_file = $ssl_dir.'/'.$domain.'.crt';
116
117         //* Create a SSL Certificate
118         if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) {
7fe908 119
146783 120             $this->ssl_certificate_changed = true;
7fe908 121
146783 122             //* Rename files if they exist
MC 123             if(file_exists($key_file)){
7fe908 124                 $app->system->rename($key_file, $key_file.'.bak');
MC 125                 $app->system->chmod($key_file.'.bak', 0400);
146783 126             }
MC 127             if(file_exists($key_file2)){
7fe908 128                 $app->system->rename($key_file2, $key_file2.'.bak');
MC 129                 $app->system->chmod($key_file2.'.bak', 0400);
146783 130             }
7fe908 131             if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak');
MC 132             if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak');
133
146783 134             $rand_file = $ssl_dir.'/random_file';
7fe908 135             $rand_data = md5(uniqid(microtime(), 1));
146783 136             for($i=0; $i<1000; $i++) {
7fe908 137                 $rand_data .= md5(uniqid(microtime(), 1));
MC 138                 $rand_data .= md5(uniqid(microtime(), 1));
139                 $rand_data .= md5(uniqid(microtime(), 1));
140                 $rand_data .= md5(uniqid(microtime(), 1));
146783 141             }
MC 142             $app->system->file_put_contents($rand_file, $rand_data);
143
7fe908 144             $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15);
146783 145
MC 146             $ssl_cnf = "        RANDFILE               = $rand_file
147
148         [ req ]
149         default_bits           = 2048
6068b7 150         default_md             = sha256
146783 151         default_keyfile        = keyfile.pem
MC 152         distinguished_name     = req_distinguished_name
153         attributes             = req_attributes
154         prompt                 = no
155         output_password        = $ssl_password
156
157         [ req_distinguished_name ]
158         C                      = ".trim($data['new']['ssl_country'])."
159         ST                     = ".trim($data['new']['ssl_state'])."
160         L                      = ".trim($data['new']['ssl_locality'])."
161         O                      = ".trim($data['new']['ssl_organisation'])."
162         OU                     = ".trim($data['new']['ssl_organisation_unit'])."
163         CN                     = $domain
164         emailAddress           = webmaster@".$data['new']['domain']."
165
166         [ req_attributes ]
167         challengePassword              = A challenge password";
168
169             $ssl_cnf_file = $ssl_dir.'/openssl.conf';
7fe908 170             $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf);
146783 171
MC 172             $rand_file = escapeshellcmd($rand_file);
173             $key_file = escapeshellcmd($key_file);
8c82ef 174             $openssl_cmd_key_file = $key_file;
146783 175             if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate
MC 176             $key_file2 = escapeshellcmd($key_file2);
8c82ef 177             $openssl_cmd_key_file2 = $key_file2;
146783 178             if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate
MC 179             $ssl_days = 3650;
180             $csr_file = escapeshellcmd($csr_file);
8c82ef 181             $openssl_cmd_csr_file = $csr_file;
146783 182             if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate
MC 183             $config_file = escapeshellcmd($ssl_cnf_file);
184             $crt_file = escapeshellcmd($crt_file);
8c82ef 185             $openssl_cmd_crt_file = $crt_file;
146783 186             if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate
MC 187
188             if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) {
7fe908 189
8c82ef 190                 exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file 2048");
6068b7 191                 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 192                 exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file -out $openssl_cmd_key_file2");
146783 193
MC 194                 if(file_exists($web_config['CA_path'].'/openssl.cnf'))
195                 {
8c82ef 196                     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");
7fe908 197                     $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
8c82ef 198                     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);
146783 199                 };
MC 200                 if (@filesize($crt_file)==0 || !file_exists($crt_file)){
8c82ef 201                     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 ");
7fe908 202                     $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
146783 203                 };
7fe908 204
146783 205             }
MC 206
7fe908 207             $app->system->chmod($key_file, 0400);
MC 208             $app->system->chmod($key_file2, 0400);
146783 209             @$app->system->unlink($config_file);
MC 210             @$app->system->unlink($rand_file);
2af58c 211             $ssl_request = $app->system->file_get_contents($csr_file);
MC 212             $ssl_cert = $app->system->file_get_contents($crt_file);
213             $ssl_key2 = $app->system->file_get_contents($key_file2);
146783 214             /* Update the DB of the (local) Server */
2af58c 215             $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 216             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
146783 217             /* Update also the master-DB of the Server-Farm */
2af58c 218             $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 219             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
146783 220         }
MC 221
222         //* Save a SSL certificate to disk
223         if($data["new"]["ssl_action"] == 'save') {
224             $this->ssl_certificate_changed = true;
225             $ssl_dir = $data["new"]["document_root"]."/ssl";
226             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
227             $key_file = $ssl_dir.'/'.$domain.'.key.org';
228             $key_file2 = $ssl_dir.'/'.$domain.'.key';
229             $csr_file = $ssl_dir.'/'.$domain.".csr";
230             $crt_file = $ssl_dir.'/'.$domain.".crt";
231             //$bundle_file = $ssl_dir.'/'.$domain.".bundle";
7fe908 232
146783 233             //* Backup files
MC 234             if(file_exists($key_file)){
7fe908 235                 $app->system->copy($key_file, $key_file.'~');
MC 236                 $app->system->chmod($key_file.'~', 0400);
146783 237             }
MC 238             if(file_exists($key_file2)){
7fe908 239                 $app->system->copy($key_file2, $key_file2.'~');
MC 240                 $app->system->chmod($key_file2.'~', 0400);
146783 241             }
7fe908 242             if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~');
MC 243             if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~');
146783 244             //if(file_exists($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'~');
7fe908 245
146783 246             //* Write new ssl files
7fe908 247             if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]);
MC 248             if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]);
146783 249             //if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file,$data["new"]["ssl_bundle"]);
7fe908 250             if(trim($data["new"]["ssl_key"]) != '') $app->system->file_put_contents($key_file2, $data["new"]["ssl_key"]);
MC 251             $app->system->chmod($key_file2, 0400);
252
146783 253             // for nginx, bundle files have to be appended to the certificate file
7fe908 254             if(trim($data["new"]["ssl_bundle"]) != ''){
146783 255                 if(file_exists($crt_file)){
MC 256                     $crt_file_contents = trim($app->system->file_get_contents($crt_file));
257                 } else {
258                     $crt_file_contents = '';
259                 }
260                 if($crt_file_contents != '') $crt_file_contents .= "\n";
261                 $crt_file_contents .= $data["new"]["ssl_bundle"];
7fe908 262                 $app->system->file_put_contents($crt_file, $app->file->unix_nl($crt_file_contents));
146783 263                 unset($crt_file_contents);
MC 264             }
265             /* Update the DB of the (local) Server */
2af58c 266             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
7fe908 267
146783 268             /* Update also the master-DB of the Server-Farm */
2af58c 269             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
7fe908 270             $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
146783 271         }
MC 272
273         //* Delete a SSL certificate
274         if($data['new']['ssl_action'] == 'del') {
275             $ssl_dir = $data['new']['document_root'].'/ssl';
276             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
277             $csr_file = $ssl_dir.'/'.$domain.'.csr';
278             $crt_file = $ssl_dir.'/'.$domain.'.crt';
279             //$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
280             if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf'))
7fe908 281             {
8c82ef 282                 exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file));
7fe908 283                 $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
MC 284             };
146783 285             $app->system->unlink($csr_file);
MC 286             $app->system->unlink($crt_file);
287             //$app->system->unlink($bundle_file);
288             /* Update the DB of the (local) Server */
2af58c 289             $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ?", $data['new']['domain']);
MC 290             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
146783 291             /* Update also the master-DB of the Server-Farm */
2af58c 292             $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ?", $data['new']['domain']);
MC 293             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
7fe908 294             $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
146783 295         }
MC 296
297     }
298
299
7fe908 300     function insert($event_name, $data) {
146783 301         global $app, $conf;
MC 302
303         $this->action = 'insert';
304         // just run the update function
7fe908 305         $this->update($event_name, $data);
146783 306
MC 307
308     }
309
310
7fe908 311     function update($event_name, $data) {
146783 312         global $app, $conf;
7fe908 313
146783 314         //* Check if the apache plugin is enabled
MC 315         if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) {
7fe908 316             $app->log('The nginx plugin cannot be used together with the apache2 plugin.', LOGLEVEL_WARN);
146783 317             return 0;
MC 318         }
7fe908 319
146783 320         if($this->action != 'insert') $this->action = 'update';
MC 321
511ba5 322         if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) {
146783 323
MC 324             $old_parent_domain_id = intval($data['old']['parent_domain_id']);
325             $new_parent_domain_id = intval($data['new']['parent_domain_id']);
326
327             // If the parent_domain_id has been changed, we will have to update the old site as well.
328             if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) {
2af58c 329                 $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $old_parent_domain_id);
146783 330                 $data['new'] = $tmp;
MC 331                 $data['old'] = $tmp;
332                 $this->action = 'update';
7fe908 333                 $this->update($event_name, $data);
146783 334             }
MC 335
336             // This is not a vhost, so we need to update the parent record instead.
2af58c 337             $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $new_parent_domain_id);
146783 338             $data['new'] = $tmp;
MC 339             $data['old'] = $tmp;
340             $this->action = 'update';
341         }
342
343         // load the server configuration options
344         $app->uses('getconf');
345         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
346
347         //* Check if this is a chrooted setup
348         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
349             $nginx_chrooted = true;
7fe908 350             $app->log('Info: nginx is chrooted.', LOGLEVEL_DEBUG);
146783 351         } else {
MC 352             $nginx_chrooted = false;
353         }
354
355         if($data['new']['document_root'] == '') {
511ba5 356             if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN);
146783 357             return 0;
MC 358         }
64ea56 359
1e6ea5 360         if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false
TB 361             || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) {
362             $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN);
146783 363             return 0;
MC 364         }
64ea56 365
146783 366         if(trim($data['new']['domain']) == '') {
7fe908 367             $app->log('domain is empty', LOGLEVEL_WARN);
146783 368             return 0;
MC 369         }
7fe908 370
MC 371         $web_folder = 'web';
372         $log_folder = 'log';
79d955 373         $old_web_folder = 'web';
MC 374         $old_log_folder = 'log';
511ba5 375         if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') {
79d955 376             // new one
2af58c 377             $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
7fe908 378             $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']);
MC 379             if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id'];
380             $web_folder = $data['new']['web_folder'];
381             $log_folder .= '/' . $subdomain_host;
382             unset($tmp);
79d955 383             
MC 384             if(isset($data['old']['parent_domain_id'])) {
385                 // old one
2af58c 386                 $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
79d955 387                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
MC 388                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
389                 $old_web_folder = $data['old']['web_folder'];
390                 $old_log_folder .= '/' . $subdomain_host;
391                 unset($tmp);
392             }
7fe908 393         }
146783 394
MC 395         // Create group and user, if not exist
396         $app->uses('system');
7fe908 397
146783 398         if($web_config['connect_userid_to_webid'] == 'y') {
MC 399             //* Calculate the uid and gid
400             $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']);
401             $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']);
402             $fixed_uid_param = '--uid '.$fixed_uid_gid;
403             $fixed_gid_param = '--gid '.$fixed_uid_gid;
7fe908 404
146783 405             //* Check if a ispconfigend user and group exists and create them
MC 406             if(!$app->system->is_group('ispconfigend')) {
407                 exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
408             }
409             if(!$app->system->is_user('ispconfigend')) {
410                 exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
411             }
412         } else {
413             $fixed_uid_param = '';
414             $fixed_gid_param = '';
415         }
416
417         $groupname = escapeshellcmd($data['new']['system_group']);
418         if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
419             exec('groupadd '.$fixed_gid_param.' '.$groupname);
420             if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname);
7fe908 421             $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG);
146783 422         }
MC 423
424         $username = escapeshellcmd($data['new']['system_user']);
425         if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) {
426             if($web_config['add_web_users_to_sshusers_group'] == 'y') {
427                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
428                 if($nginx_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");
429             } else {
430                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
431                 if($nginx_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");
432             }
7fe908 433             $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG);
146783 434         }
MC 435
436         //* If the client of the site has been changed, we have a change of the document root
437         if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
438
439             //* Get the old client ID
2af58c 440             $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']);
146783 441             $old_client_id = intval($old_client['client_id']);
MC 442             unset($old_client);
443
444             //* Remove the old symlinks
7fe908 445             $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
146783 446             if(is_array($tmp_symlinks_array)) {
MC 447                 foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 448                     $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink);
MC 449                     $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
146783 450                     // Remove trailing slash
MC 451                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
452                     // create the symlinks, if not exist
453                     if(is_link($tmp_symlink)) {
454                         exec('rm -f '.escapeshellcmd($tmp_symlink));
7fe908 455                         $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
146783 456                     }
MC 457                 }
458             }
459
511ba5 460             if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") {
146783 461                 //* Move the site data
7fe908 462                 $tmp_docroot = explode('/', $data['new']['document_root']);
146783 463                 unset($tmp_docroot[count($tmp_docroot)-1]);
7fe908 464                 $new_dir = implode('/', $tmp_docroot);
146783 465
7fe908 466                 $tmp_docroot = explode('/', $data['old']['document_root']);
146783 467                 unset($tmp_docroot[count($tmp_docroot)-1]);
7fe908 468                 $old_dir = implode('/', $tmp_docroot);
146783 469
MC 470                 //* 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
471                 if(@is_dir($data['new']['document_root'])) {
7fe908 472                     $app->system->web_folder_protection($data['new']['document_root'], false);
MC 473                     $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'));
474                     $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);
146783 475                 }
3fb802 476                 
TB 477                 //* Unmount the old log directory bfore we move the log dir
a9b325 478                 //exec('fuser -km '.escapeshellcmd($old_dir.'/log'));
3fb802 479                 exec('umount '.escapeshellcmd($old_dir.'/log'));
7fe908 480
146783 481                 //* Create new base directory, if it does not exist yet
MC 482                 if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir);
7fe908 483                 $app->system->web_folder_protection($data['old']['document_root'], false);
146783 484                 exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir));
MC 485                 //$app->system->rename($data['old']['document_root'],$new_dir);
7fe908 486                 $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG);
146783 487
MC 488                 // Handle the change in php_open_basedir
7fe908 489                 $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']);
146783 490
MC 491                 //* Change the owner of the website files to the new website owner
492                 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);
493
494                 //* Change the home directory and group of the website user
495                 $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod';
496                 $command .= ' --home '.escapeshellcmd($data['new']['document_root']);
497                 $command .= ' --gid '.escapeshellcmd($data['new']['system_group']);
498                 $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
499                 exec($command);
500             }
501
502             if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
7fe908 503
146783 504             //* Change the log mount
074a57 505             /*
79d955 506             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
7fe908 507             $app->system->removeLine('/etc/fstab', $fstab_line);
79d955 508             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
ff5b86 509             $app->system->removeLine('/etc/fstab', $fstab_line);
074a57 510             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
TB 511             $app->system->removeLine('/etc/fstab', $fstab_line);
512             */
513             
514             $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
515             
516             if($web_config['network_filesystem'] == 'y') {
517                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
518                 $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
519             } else {
520                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
521                 $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
522             }
3fb802 523             
TB 524             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
146783 525
MC 526         }
527
528         //print_r($data);
529
530         // Check if the directories are there and create them if necessary.
7fe908 531         $app->system->web_folder_protection($data['new']['document_root'], false);
MC 532
146783 533         if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder);
MC 534         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 535         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/stats');
146783 536         //if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder);
MC 537         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
538         if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
539         if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp');
540         //if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav');
7fe908 541
146783 542         //* Create the new private directory
MC 543         if(!is_dir($data['new']['document_root'].'/private')) {
544             $app->system->mkdirpath($data['new']['document_root'].'/private');
7fe908 545             $app->system->chmod($data['new']['document_root'].'/private', 0710);
MC 546             $app->system->chown($data['new']['document_root'].'/private', $username);
547             $app->system->chgrp($data['new']['document_root'].'/private', $groupname);
146783 548         }
7fe908 549
MC 550
146783 551         // Remove the symlink for the site, if site is renamed
MC 552         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
553             if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
79d955 554             if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder);
7fe908 555
146783 556             //* remove old log mount
79d955 557             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
7fe908 558             $app->system->removeLine('/etc/fstab', $fstab_line);
MC 559
146783 560             //* Unmount log directory
a9b325 561             //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
79d955 562             exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
146783 563         }
7fe908 564
146783 565         //* Create the log dir if nescessary and mount it
MC 566         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)) {
567             if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder);
568             if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']);
569             $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder);
7fe908 570             $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root');
MC 571             $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root');
572             $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
146783 573             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
MC 574             //* add mountpoint to fstab
ff5b86 575             $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
7fe908 576             $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
146783 577         }
7fe908 578
MC 579         $app->system->web_folder_protection($data['new']['document_root'], true);
146783 580
MC 581         // Get the client ID
2af58c 582         $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']);
146783 583         $client_id = intval($client['client_id']);
MC 584         unset($client);
585
586         // Remove old symlinks, if site is renamed
587         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
7fe908 588             $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
146783 589             if(is_array($tmp_symlinks_array)) {
MC 590                 foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 591                     $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
MC 592                     $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
146783 593                     // Remove trailing slash
MC 594                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
595                     // remove the symlinks, if not exist
596                     if(is_link($tmp_symlink)) {
597                         exec('rm -f '.escapeshellcmd($tmp_symlink));
7fe908 598                         $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
146783 599                     }
MC 600                 }
601             }
602         }
603
604         // Create the symlinks for the sites
7fe908 605         $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
146783 606         if(is_array($tmp_symlinks_array)) {
MC 607             foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 608                 $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
MC 609                 $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink);
146783 610                 // Remove trailing slash
MC 611                 if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
612                 //* Remove symlink if target folder has been changed.
613                 if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) {
614                     $app->system->unlink($tmp_symlink);
615                 }
616                 // create the symlinks, if not exist
617                 if(!is_link($tmp_symlink)) {
7fe908 618                     //     exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
146783 619                     if ($web_config["website_symlinks_rel"] == 'y') {
MC 620                         $this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink));
621                     } else {
622                         exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
623                     }
624
7fe908 625                     $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG);
146783 626                 }
MC 627             }
628         }
629
630
631
7fe908 632         // Install the Standard or Custom Error, Index and other related files
MC 633         // /usr/local/ispconfig/server/conf is for the standard files
634         // /usr/local/ispconfig/server/conf-custom is for the custom files
635         // setting a local var here
636
637         // normally $conf['templates'] = "/usr/local/ispconfig/server/conf";
511ba5 638         if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) {
7fe908 639
MC 640             // Copy the error pages
146783 641             if($data['new']['errordocs']) {
MC 642                 $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
7fe908 643                 if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 644                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
146783 645                 }
MC 646                 else {
647                     if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
648                         exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
649                     }
650                     else {
7fe908 651                         exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
146783 652                     }
MC 653                 }
654                 exec('chmod -R a+r '.$error_page_path);
655             }
656
7fe908 657             if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) {
f0dfa9 658                 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');
7fe908 659
MC 660                 if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) {
f0dfa9 661                     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 . '/');
7fe908 662                 }
MC 663                 if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) {
f0dfa9 664                     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 . '/');
7fe908 665                 }
4f1e6a 666                 //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) {
TB 667                 //    exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
668                 //}
f0dfa9 669             } else {
146783 670                 if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) {
f0dfa9 671                     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 672                 } else {
673                     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');
674                     if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){
675                         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 . '/');
676                     }
677                     if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){
678                         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 . '/');
679                     }
4f1e6a 680                     //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
146783 681                 }
MC 682             }
683             exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
684
685             //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
511ba5 686         } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
7fe908 687
146783 688             $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
7fe908 689             if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 690                 exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
146783 691             }
MC 692             else {
693                 if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
694                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
695                 }
696                 else {
7fe908 697                     exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
146783 698                 }
MC 699             }
700             exec('chmod -R a+r '.$error_page_path);
701             exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
702         }  // end copy error docs
703
511ba5 704         // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias
146783 705         if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') {
MC 706             if($data['new']['hd_quota'] > 0) {
707                 $blocks_soft = $data['new']['hd_quota'] * 1024;
708                 $blocks_hard = $blocks_soft + 1024;
709             } else {
710                 $blocks_soft = $blocks_hard = 0;
711             }
712             exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
713             exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
714         }
715
716         if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
717             // Chown and chmod the directories below the document root
718             $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
719             // The document root itself has to be owned by root in normal level and by the web owner in security level 20
720             if($web_config['security_level'] == 20) {
721                 $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
722             } else {
723                 $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
724             }
725         }
726
727         //* add the nginx 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
728         if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user']));
7fe908 729
146783 730         //* If the security level is set to high
MC 731         if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
7fe908 732
MC 733             $app->system->web_folder_protection($data['new']['document_root'], false);
734
146783 735             //* Check if we have the new private folder and create it if nescessary
MC 736             if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private');
7fe908 737
146783 738             if($web_config['security_level'] == 20) {
7fe908 739
MC 740                 $app->system->chmod($data['new']['document_root'], 0755);
97b556 741                 $app->system->chmod($data['new']['document_root'].'/web', 0751);
146783 742                 //$app->system->chmod($data['new']['document_root'].'/webdav',0710);
7fe908 743                 $app->system->chmod($data['new']['document_root'].'/private', 0710);
MC 744                 $app->system->chmod($data['new']['document_root'].'/ssl', 0755);
146783 745
MC 746                 // make tmp directory writable for nginx and the website users
5aedfd 747                 $app->system->chmod($data['new']['document_root'].'/tmp', 0770);
7fe908 748
146783 749                 // Set Log directory to 755 to make the logs accessible by the FTP user
MC 750                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 751                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
146783 752                 }
7fe908 753
146783 754                 if($web_config['add_web_users_to_sshusers_group'] == 'y') {
MC 755                     $command = 'usermod';
756                     $command .= ' --groups sshusers';
757                     $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
758                     $this->_exec($command);
759                 }
760
761                 //* if we have a chrooted nginx environment
762                 if($nginx_chrooted) {
763                     $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
764
765                     //* add the nginx user to the client group in the chroot environment
766                     $tmp_groupfile = $app->system->server_conf['group_datei'];
767                     $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group';
768                     $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user']));
769                     $app->system->server_conf['group_datei'] = $tmp_groupfile;
770                     unset($tmp_groupfile);
771                 }
7fe908 772
146783 773                 //* Chown all default directories
7fe908 774                 $app->system->chown($data['new']['document_root'], 'root');
MC 775                 $app->system->chgrp($data['new']['document_root'], 'root');
776                 $app->system->chown($data['new']['document_root'].'/cgi-bin', $username);
777                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname);
146783 778                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 779                     $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false);
MC 780                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false);
146783 781                 }
7fe908 782                 $app->system->chown($data['new']['document_root'].'/ssl', 'root');
MC 783                 $app->system->chgrp($data['new']['document_root'].'/ssl', 'root');
784                 $app->system->chown($data['new']['document_root'].'/tmp', $username);
785                 $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname);
786                 $app->system->chown($data['new']['document_root'].'/web', $username);
787                 $app->system->chgrp($data['new']['document_root'].'/web', $groupname);
788                 $app->system->chown($data['new']['document_root'].'/web/error', $username);
789                 $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname);
790                 $app->system->chown($data['new']['document_root'].'/web/stats', $username);
791                 $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
146783 792                 //$app->system->chown($data['new']['document_root'].'/webdav',$username);
MC 793                 //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
7fe908 794                 $app->system->chown($data['new']['document_root'].'/private', $username);
MC 795                 $app->system->chgrp($data['new']['document_root'].'/private', $groupname);
146783 796
MC 797                 // If the security Level is set to medium
798             } else {
799
7fe908 800                 $app->system->chmod($data['new']['document_root'], 0755);
MC 801                 $app->system->chmod($data['new']['document_root'].'/web', 0755);
146783 802                 //$app->system->chmod($data['new']['document_root'].'/webdav',0755);
7fe908 803                 $app->system->chmod($data['new']['document_root'].'/ssl', 0755);
MC 804                 $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755);
805
146783 806                 // make temp directory writable for nginx and the website users
5aedfd 807                 $app->system->chmod($data['new']['document_root'].'/tmp', 0770);
7fe908 808
146783 809                 // Set Log directory to 755 to make the logs accessible by the FTP user
MC 810                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 811                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
146783 812                 }
7fe908 813
MC 814                 $app->system->chown($data['new']['document_root'], 'root');
815                 $app->system->chgrp($data['new']['document_root'], 'root');
816                 $app->system->chown($data['new']['document_root'].'/cgi-bin', $username);
817                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname);
146783 818                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 819                     $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false);
MC 820                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false);
146783 821                 }
7fe908 822
MC 823                 $app->system->chown($data['new']['document_root'].'/ssl', 'root');
824                 $app->system->chgrp($data['new']['document_root'].'/ssl', 'root');
825                 $app->system->chown($data['new']['document_root'].'/tmp', $username);
826                 $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname);
827                 $app->system->chown($data['new']['document_root'].'/web', $username);
828                 $app->system->chgrp($data['new']['document_root'].'/web', $groupname);
829                 $app->system->chown($data['new']['document_root'].'/web/error', $username);
830                 $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname);
831                 $app->system->chown($data['new']['document_root'].'/web/stats', $username);
832                 $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
146783 833                 //$app->system->chown($data['new']['document_root'].'/webdav',$username);
MC 834                 //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
835             }
511ba5 836         } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) &&
DM 837                  (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) {
838
146783 839             if($web_config['security_level'] == 20) {
7fe908 840                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710);
MC 841                 $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
842                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname);
843                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username);
844                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname);
845                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username);
846                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname);
847             } else {
848                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755);
849                 $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
850                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname);
851                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username);
852                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname);
853                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username);
854                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname);
855             }
856         }
857
146783 858         //* Protect web folders
7fe908 859         $app->system->web_folder_protection($data['new']['document_root'], true);
MC 860
146783 861         if($data['new']['type'] == 'vhost') {
7fe908 862             // Change the ownership of the error log to the root user
MC 863             if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log'));
864             $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
865             $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
866         }
146783 867
MC 868         // Change the ownership of the error log to the owner of the website
869         /*
870         if(!@is_file($data['new']['document_root'].'/log/error.log')) exec('touch '.escapeshellcmd($data['new']['document_root']).'/log/error.log');
871         $app->system->chown($data['new']['document_root'].'/log/error.log',$username);
872         $app->system->chgrp($data['new']['document_root'].'/log/error.log',$groupname);
873         */
874
875
876         /*
877         //* Write the custom php.ini file, if custom_php_ini filed is not empty
878         $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
879         if(!is_dir($web_config['website_basedir'].'/conf')) mkdir($web_config['website_basedir'].'/conf');
880         if(trim($data['new']['custom_php_ini']) != '') {
881             $has_custom_php_ini = true;
882             if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir);
883             $php_ini_content = '';
884             if($data['new']['php'] == 'mod') {
885                 $master_php_ini_path = $web_config['php_ini_path_apache'];
886             } else {
887                 if($data["new"]['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
888                     $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
889                 } else {
890                     $master_php_ini_path = $web_config['php_ini_path_cgi'];
891                 }
892             }
893             if($master_php_ini_path != '' && substr($master_php_ini_path,-7) == 'php.ini' && is_file($master_php_ini_path)) {
894                 $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
895             }
896             $php_ini_content .= str_replace("\r",'',trim($data['new']['custom_php_ini']));
897             $app->system->file_put_contents($custom_php_ini_dir.'/php.ini',$php_ini_content);
898         } else {
899             $has_custom_php_ini = false;
900             if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini');
901         }
902         */
903
904         //* Create the vhost config file
905         $app->load('tpl');
906
907         $tpl = new tpl();
908         $tpl->newTemplate('nginx_vhost.conf.master');
909
6c424f 910         // IPv4
FS 911
912         //* use ip-mapping for web-mirror
913         if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) {
914             $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?";
915             $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']);
916             $data['new']['ip_address'] = $newip['destination_ip'];
917             unset($newip);
918         }
919
146783 920         $vhost_data = $data['new'];
6c424f 921
146783 922         //unset($vhost_data['ip_address']);
MC 923         $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder;
924         $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder;
925         $vhost_data['web_basedir'] = $web_config['website_basedir'];
7fe908 926
146783 927         // IPv6
MC 928         if($data['new']['ipv6_address'] != ''){
929             $tpl->setVar('ipv6_enabled', 1);
930             if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') {
931                 if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') {
7fe908 932                     $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']);
MC 933                     $explode_v6=explode(':', $data['new']['ipv6_address']);
146783 934
MC 935                     for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) {
7fe908 936                         $explode_v6[$i] = $explode_v6prefix[$i];
146783 937                     }
7fe908 938                     $data['new']['ipv6_address'] = implode(':', $explode_v6);
146783 939                     $vhost_data['ipv6_address'] = $data['new']['ipv6_address'];
MC 940                 }
941             }
942         }
7fe908 943
146783 944         // PHP-FPM
MC 945         // Support for multiple PHP versions
946         /*
947         if(trim($data['new']['fastcgi_php_version']) != ''){
948             $default_php_fpm = false;
949             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']));
950             if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
951         } else {
952             $default_php_fpm = true;
953         }
954         */
02e7ea 955         if($data['new']['php'] == 'php-fpm'){
146783 956             if(trim($data['new']['fastcgi_php_version']) != ''){
MC 957                 $default_php_fpm = false;
958                 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']));
7fe908 959                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
146783 960             } else {
MC 961                 $default_php_fpm = true;
962             }
963         } else {
964             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){
965                 $default_php_fpm = false;
966                 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']));
7fe908 967                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
146783 968             } else {
MC 969                 $default_php_fpm = true;
970             }
971         }
7fe908 972
146783 973         if($default_php_fpm){
MC 974             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
975         } else {
976             $pool_dir = $custom_php_fpm_pool_dir;
977         }
ab79c2 978         $pool_dir = trim($pool_dir);
7fe908 979         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
146783 980         $pool_name = 'web'.$data['new']['domain_id'];
MC 981         $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
7fe908 982         if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
MC 983
146783 984         if($data['new']['php_fpm_use_socket'] == 'y'){
MC 985             $use_tcp = 0;
986             $use_socket = 1;
987         } else {
988             $use_tcp = 1;
989             $use_socket = 0;
990         }
991         $tpl->setVar('use_tcp', $use_tcp);
992         $tpl->setVar('use_socket', $use_socket);
993         $fpm_socket = $socket_dir.$pool_name.'.sock';
994         $tpl->setVar('fpm_socket', $fpm_socket);
7fe908 995         $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(), 1)).'.htm');
146783 996         $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1;
7fe908 997
146783 998         // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support.
MC 999         if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm';
7fe908 1000
146783 1001         // Custom rewrite rules
MC 1002         /*
1003         $final_rewrite_rules = array();
1004         $custom_rewrite_rules = $data['new']['rewrite_rules'];
1005         // Make sure we only have Unix linebreaks
1006         $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules);
1007         $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules);
1008         $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules);
1009         if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){
1010             foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){
1011                 $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1012             }
1013         }
1014         $tpl->setLoop('rewrite_rules', $final_rewrite_rules);
1015         */
7fe908 1016
146783 1017         // Custom rewrite rules
MC 1018         $final_rewrite_rules = array();
7fe908 1019
146783 1020         if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') {
MC 1021             $custom_rewrite_rules = trim($data['new']['rewrite_rules']);
1022             $custom_rewrites_are_valid = true;
1023             // use this counter to make sure all curly brackets are properly closed
1024             $if_level = 0;
1025             // Make sure we only have Unix linebreaks
1026             $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules);
1027             $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules);
1028             $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules);
1029             if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){
1030                 foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){
1031                     // ignore comments
7fe908 1032                     if(substr(ltrim($custom_rewrite_rule_line), 0, 1) == '#'){
146783 1033                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
MC 1034                         continue;
1035                     }
1036                     // empty lines
1037                     if(trim($custom_rewrite_rule_line) == ''){
1038                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1039                         continue;
1040                     }
1041                     // rewrite
1042                     if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){
1043                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1044                         continue;
1045                     }
b5b613 1046                     if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){
FT 1047                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1048                         continue;
1049                     }
1050                     if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){
1051                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1052                         continue;
1053                     }
1054                     if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){
1055                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1056                         continue;
1057                     }
146783 1058                     // if
MC 1059                     if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){
1060                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1061                         $if_level += 1;
1062                         continue;
1063                     }
1064                     // if - check for files, directories, etc.
1065                     if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){
1066                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1067                         $if_level += 1;
1068                         continue;
1069                     }
1070                     // break
1071                     if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){
1072                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1073                         continue;
1074                     }
1075                     // return code [ text ]
1076                     if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){
1077                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1078                         continue;
1079                     }
1080                     // return code URL
1081                     // return URL
1082                     if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){
1083                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1084                         continue;
1085                     }
1086                     // set
1087                     if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){
1088                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1089                         continue;
1090                     }
1091                     // closing curly bracket
1092                     if(trim($custom_rewrite_rule_line) == '}'){
1093                         $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line);
1094                         $if_level -= 1;
1095                         continue;
1096                     }
1097                     $custom_rewrites_are_valid = false;
1098                     break;
1099                 }
1100             }
1101             if(!$custom_rewrites_are_valid || $if_level != 0){
1102                 $final_rewrite_rules = array();
1103             }
1104         }
1105         $tpl->setLoop('rewrite_rules', $final_rewrite_rules);
7fe908 1106
146783 1107         // Custom nginx directives
MC 1108         $final_nginx_directives = array();
1fa8f4 1109         if(intval($data['new']['directive_snippets_id']) > 0){
2af58c 1110             $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']);
1fa8f4 1111             if(isset($snippet['snippet'])){
FT 1112                 $nginx_directives = $snippet['snippet'];
1113             } else {
1114                 $nginx_directives = $data['new']['nginx_directives'];
1115             }
86bc65 1116             if($data['new']['enable_pagespeed'] == 'y'){
MC 1117                 // if PageSpeed is already enabled, don't add configuration again
1118                 if(stripos($nginx_directives, 'pagespeed') !== false){
1119                     $vhost_data['enable_pagespeed'] = false;
1120                 } else {
1121                     $vhost_data['enable_pagespeed'] = true;
1122                 }
1123             } else {
1124                 $vhost_data['enable_pagespeed'] = false;
1125             }
1fa8f4 1126         } else {
FT 1127             $nginx_directives = $data['new']['nginx_directives'];
86bc65 1128             $vhost_data['enable_pagespeed'] = false;
1fa8f4 1129         }
146783 1130         // Make sure we only have Unix linebreaks
MC 1131         $nginx_directives = str_replace("\r\n", "\n", $nginx_directives);
1132         $nginx_directives = str_replace("\r", "\n", $nginx_directives);
1133         $nginx_directive_lines = explode("\n", $nginx_directives);
1134         if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){
c02d3f 1135             $trans = array('{DOCROOT}' => $vhost_data['web_document_root_www'], '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_socket : '127.0.0.1:'.$vhost_data['fpm_port']).';');
146783 1136             foreach($nginx_directive_lines as $nginx_directive_line){
c02d3f 1137                 $final_nginx_directives[] = array('nginx_directive' => strtr($nginx_directive_line, $trans));
146783 1138             }
MC 1139         }
1140         $tpl->setLoop('nginx_directives', $final_nginx_directives);
1141
1142         // Check if a SSL cert exists
1143         $ssl_dir = $data['new']['document_root'].'/ssl';
1144         $domain = $data['new']['ssl_domain'];
1145         $key_file = $ssl_dir.'/'.$domain.'.key';
1146         $crt_file = $ssl_dir.'/'.$domain.'.crt';
1147
1148         if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
1149             $vhost_data['ssl_enabled'] = 1;
7fe908 1150             $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG);
146783 1151         } else {
MC 1152             $vhost_data['ssl_enabled'] = 0;
7fe908 1153             $app->log('SSL Disabled. '.$domain, LOGLEVEL_DEBUG);
146783 1154         }
MC 1155
1156         // Set SEO Redirect
1157         if($data['new']['seo_redirect'] != ''){
1158             $vhost_data['seo_redirect_enabled'] = 1;
1159             $tmp_seo_redirects = $this->get_seo_redirects($data['new']);
1160             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1161                 foreach($tmp_seo_redirects as $key => $val){
1162                     $vhost_data[$key] = $val;
1163                 }
1164             } else {
1165                 $vhost_data['seo_redirect_enabled'] = 0;
1166             }
1167         } else {
1168             $vhost_data['seo_redirect_enabled'] = 0;
1169         }
7fe908 1170
MC 1171
146783 1172
MC 1173         // Rewrite rules
1174         $own_rewrite_rules = array();
1175         $rewrite_rules = array();
1176         $local_rewrite_rules = array();
1177         if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') {
7fe908 1178             if(substr($data['new']['redirect_path'], -1) != '/') $data['new']['redirect_path'] .= '/';
MC 1179             if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){
146783 1180                 if($data['new']['redirect_type'] != 'proxy'){
7fe908 1181                     $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'], 8);
146783 1182                 } else {
7fe908 1183                     $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'], 8);
146783 1184                 }
MC 1185             }
7fe908 1186
146783 1187             // Custom proxy directives
MC 1188             if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){
1189                 $final_proxy_directives = array();
1190                 $proxy_directives = $data['new']['proxy_directives'];
1191                 // Make sure we only have Unix linebreaks
1192                 $proxy_directives = str_replace("\r\n", "\n", $proxy_directives);
1193                 $proxy_directives = str_replace("\r", "\n", $proxy_directives);
1194                 $proxy_directive_lines = explode("\n", $proxy_directives);
1195                 if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){
1196                     foreach($proxy_directive_lines as $proxy_directive_line){
1197                         $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line);
1198                     }
1199                 }
1200             } else {
1201                 $final_proxy_directives = false;
1202             }
1203
1204             switch($data['new']['subdomain']) {
7fe908 1205             case 'www':
MC 1206                 $exclude_own_hostname = '';
1207                 if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path
1208                     if($data['new']['redirect_type'] == 'proxy'){
1209                         $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';';
1210                         $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1);
1211                         break;
1212                     }
1213                     $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/';
1214                 } else { // URL - check if URL is local
1215                     $tmp_redirect_path = $data['new']['redirect_path'];
1216                     if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7);
1217                     $tmp_redirect_path_parts = parse_url($tmp_redirect_path);
1218                     if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){
1219                         // URL is local
1220                         if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1);
1221                         if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path'];
1222                         //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))';
1223                         if($data['new']['redirect_type'] == 'proxy'){
1224                             $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';';
1225                             $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path'];
1226                             break;
1227                         } else {
1228                             $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/';
1229                             $exclude_own_hostname = $tmp_redirect_path_parts['host'];
1230                         }
1231                     } else {
1232                         // external URL
1233                         $rewrite_exclude = '(.?)/';
1234                         if($data['new']['redirect_type'] == 'proxy'){
1235                             $vhost_data['use_proxy'] = 'y';
1236                             $rewrite_subdir = $tmp_redirect_path_parts['path'];
1237                             if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1);
1238                             if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/';
1239                             if($rewrite_subdir == '/') $rewrite_subdir = '';
1240                         }
1241                     }
1242                     unset($tmp_redirect_path);
1243                     unset($tmp_redirect_path_parts);
1244                 }
1245                 $own_rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
1246                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'],
1247                     'rewrite_target'  => $data['new']['redirect_path'],
1248                     'rewrite_exclude' => $rewrite_exclude,
1249                     'rewrite_subdir' => $rewrite_subdir,
1250                     'exclude_own_hostname' => $exclude_own_hostname,
1251                     'proxy_directives' => $final_proxy_directives,
1252                     'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true),
1253                     'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false));
1254                 break;
1255             case '*':
1256                 $exclude_own_hostname = '';
1257                 if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path
1258                     if($data['new']['redirect_type'] == 'proxy'){
1259                         $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';';
1260                         $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1);
1261                         break;
1262                     }
1263                     $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/';
1264                 } else { // URL - check if URL is local
1265                     $tmp_redirect_path = $data['new']['redirect_path'];
1266                     if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7);
1267                     $tmp_redirect_path_parts = parse_url($tmp_redirect_path);
1268
1269                     //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){
1270                     if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){
1271                         // URL is local
1272                         if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1);
1273                         if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path'];
1274                         //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))';
1275                         if($data['new']['redirect_type'] == 'proxy'){
1276                             $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';';
1277                             $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path'];
1278                             break;
1279                         } else {
1280                             $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/';
1281                             $exclude_own_hostname = $tmp_redirect_path_parts['host'];
1282                         }
1283                     } else {
1284                         // external URL
1285                         $rewrite_exclude = '(.?)/';
1286                         if($data['new']['redirect_type'] == 'proxy'){
1287                             $vhost_data['use_proxy'] = 'y';
1288                             $rewrite_subdir = $tmp_redirect_path_parts['path'];
1289                             if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1);
1290                             if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/';
1291                             if($rewrite_subdir == '/') $rewrite_subdir = '';
1292                         }
1293                     }
1294                     unset($tmp_redirect_path);
1295                     unset($tmp_redirect_path_parts);
1296                 }
1297                 $own_rewrite_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']),
1298                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'],
1299                     'rewrite_target'  => $data['new']['redirect_path'],
1300                     'rewrite_exclude' => $rewrite_exclude,
1301                     'rewrite_subdir' => $rewrite_subdir,
1302                     'exclude_own_hostname' => $exclude_own_hostname,
1303                     'proxy_directives' => $final_proxy_directives,
1304                     'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true),
1305                     'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false));
1306                 break;
1307             default:
1308                 if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path
146783 1309                     $exclude_own_hostname = '';
7fe908 1310                     if($data['new']['redirect_type'] == 'proxy'){
MC 1311                         $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';';
1312                         $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1);
1313                         break;
1314                     }
1315                     $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/';
1316                 } else { // URL - check if URL is local
1317                     $tmp_redirect_path = $data['new']['redirect_path'];
1318                     if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7);
1319                     $tmp_redirect_path_parts = parse_url($tmp_redirect_path);
1320                     if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){
1321                         // URL is local
1322                         if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1);
1323                         if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path'];
1324                         //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))';
146783 1325                         if($data['new']['redirect_type'] == 'proxy'){
MC 1326                             $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';';
7fe908 1327                             $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path'];
146783 1328                             break;
MC 1329                         } else {
7fe908 1330                             $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/';
MC 1331                             $exclude_own_hostname = $tmp_redirect_path_parts['host'];
146783 1332                         }
7fe908 1333                     } else {
MC 1334                         // external URL
1335                         $rewrite_exclude = '(.?)/';
146783 1336                         if($data['new']['redirect_type'] == 'proxy'){
7fe908 1337                             $vhost_data['use_proxy'] = 'y';
MC 1338                             $rewrite_subdir = $tmp_redirect_path_parts['path'];
1339                             if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1);
1340                             if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/';
1341                             if($rewrite_subdir == '/') $rewrite_subdir = '';
146783 1342                         }
MC 1343                     }
7fe908 1344                     unset($tmp_redirect_path);
MC 1345                     unset($tmp_redirect_path_parts);
1346                 }
1347                 $own_rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
1348                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'],
1349                     'rewrite_target'  => $data['new']['redirect_path'],
1350                     'rewrite_exclude' => $rewrite_exclude,
1351                     'rewrite_subdir' => $rewrite_subdir,
1352                     'exclude_own_hostname' => $exclude_own_hostname,
1353                     'proxy_directives' => $final_proxy_directives,
1354                     'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true),
1355                     'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false));
146783 1356             }
MC 1357         }
1358
1359         $tpl->setVar($vhost_data);
7fe908 1360
146783 1361         $server_alias = array();
7fe908 1362
146783 1363         // get autoalias
MC 1364         $auto_alias = $web_config['website_autoalias'];
1365         if($auto_alias != '') {
1366             // get the client username
2af58c 1367             $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id);
146783 1368             $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]');
MC 1369             $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']);
1370             $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias);
1371             unset($client);
1372             unset($aa_search);
1373             unset($aa_replace);
1374             $server_alias[] .= $auto_alias.' ';
1375         }
7fe908 1376
146783 1377         switch($data['new']['subdomain']) {
7fe908 1378         case 'www':
MC 1379             $server_alias[] = 'www.'.$data['new']['domain'].' ';
1380             break;
1381         case '*':
1382             $server_alias[] = '*.'.$data['new']['domain'].' ';
1383             break;
146783 1384         }
MC 1385
1386         // get alias domains (co-domains and subdomains)
2af58c 1387         $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']);
146783 1388         $alias_seo_redirects = array();
MC 1389         if(is_array($aliases)) {
1390             foreach($aliases as $alias) {
7fe908 1391
146783 1392                 // Custom proxy directives
MC 1393                 if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){
1394                     $final_proxy_directives = array();
1395                     $proxy_directives = $alias['proxy_directives'];
1396                     // Make sure we only have Unix linebreaks
1397                     $proxy_directives = str_replace("\r\n", "\n", $proxy_directives);
1398                     $proxy_directives = str_replace("\r", "\n", $proxy_directives);
1399                     $proxy_directive_lines = explode("\n", $proxy_directives);
1400                     if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){
1401                         foreach($proxy_directive_lines as $proxy_directive_line){
1402                             $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line);
1403                         }
1404                     }
1405                 } else {
1406                     $final_proxy_directives = false;
1407                 }
7fe908 1408
MC 1409                 if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'], 0, 1) == '/') {
146783 1410                     switch($alias['subdomain']) {
7fe908 1411                     case 'www':
MC 1412                         $server_alias[] = 'www.'.$alias['domain'].' '.$alias['domain'].' ';
1413                         break;
1414                     case '*':
1415                         $server_alias[] = '*.'.$alias['domain'].' '.$alias['domain'].' ';
1416                         break;
1417                     default:
1418                         $server_alias[] = $alias['domain'].' ';
1419                         break;
146783 1420                     }
7fe908 1421                     $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG);
MC 1422
146783 1423                     // Add SEO redirects for alias domains
MC 1424                     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'))){
1425                         $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_');
1426                         if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1427                             $alias_seo_redirects[] = $tmp_seo_redirects;
1428                         }
1429                     }
1430                 }
1431
7fe908 1432                 // Local Rewriting (inside vhost server {} container)
MC 1433                 if($alias['redirect_type'] != '' && substr($alias['redirect_path'], 0, 1) == '/' && $alias['redirect_type'] != 'proxy') {  // proxy makes no sense with local path
1434                     if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/';
1435                     $rewrite_exclude = '(?!/\b('.substr($alias['redirect_path'], 1, -1).(substr($alias['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/';
1436                     switch($alias['subdomain']) {
1437                     case 'www':
1438                         // example.com
1439                         $local_rewrite_rules[] = array( 'local_redirect_origin_domain'  => $alias['domain'],
1440                             'local_redirect_operator' => '=',
1441                             'local_redirect_exclude' => $rewrite_exclude,
1442                             'local_redirect_target' => $alias['redirect_path'],
1443                             'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']);
1444
1445                         // www.example.com
1446                         $local_rewrite_rules[] = array( 'local_redirect_origin_domain'  => 'www.'.$alias['domain'],
1447                             'local_redirect_operator' => '=',
1448                             'local_redirect_exclude' => $rewrite_exclude,
1449                             'local_redirect_target' => $alias['redirect_path'],
1450                             'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']);
1451                         break;
1452                     case '*':
1453                         $local_rewrite_rules[] = array( 'local_redirect_origin_domain'  => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$',
1454                             'local_redirect_operator' => '~*',
1455                             'local_redirect_exclude' => $rewrite_exclude,
1456                             'local_redirect_target' => $alias['redirect_path'],
1457                             'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']);
1458                         break;
1459                     default:
1460                         $local_rewrite_rules[] = array( 'local_redirect_origin_domain'  => $alias['domain'],
1461                             'local_redirect_operator' => '=',
1462                             'local_redirect_exclude' => $rewrite_exclude,
1463                             'local_redirect_target' => $alias['redirect_path'],
1464                             'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']);
146783 1465                     }
MC 1466                 }
7fe908 1467
146783 1468                 // External Rewriting (extra server {} containers)
7fe908 1469                 if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'], 0, 1) != '/') {
MC 1470                     if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/';
1471                     if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){
146783 1472                         if($alias['redirect_type'] != 'proxy'){
7fe908 1473                             $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'], 8);
146783 1474                         } else {
7fe908 1475                             $alias['redirect_path'] = 'http'.substr($alias['redirect_path'], 8);
146783 1476                         }
MC 1477                     }
1478
7fe908 1479                     switch($alias['subdomain']) {
MC 1480                     case 'www':
1481                         if($alias['redirect_type'] == 'proxy'){
1482                             $tmp_redirect_path = $alias['redirect_path'];
1483                             $tmp_redirect_path_parts = parse_url($tmp_redirect_path);
1484                             $rewrite_subdir = $tmp_redirect_path_parts['path'];
1485                             if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1);
1486                             if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/';
1487                             if($rewrite_subdir == '/') $rewrite_subdir = '';
1488                         }
1489
1490                         if($alias['redirect_type'] != 'proxy'){
1491                             if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1);
1492                         }
1493                         // Add SEO redirects for alias domains
1494                         $alias_seo_redirects2 = array();
1495                         if($alias['seo_redirect'] != ''){
1496                             $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none');
1497                             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1498                                 $alias_seo_redirects2[] = $tmp_seo_redirects;
146783 1499                             }
7fe908 1500                         }
MC 1501                         $rewrite_rules[] = array( 'rewrite_domain'  => $alias['domain'],
1502                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'],
1503                             'rewrite_target'  => $alias['redirect_path'],
1504                             'rewrite_subdir' => $rewrite_subdir,
1505                             'proxy_directives' => $final_proxy_directives,
1506                             'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true),
1507                             'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false),
1508                             'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false));
1509
1510                         // Add SEO redirects for alias domains
1511                         $alias_seo_redirects2 = array();
1512                         if($alias['seo_redirect'] != ''){
1513                             $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www');
1514                             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1515                                 $alias_seo_redirects2[] = $tmp_seo_redirects;
146783 1516                             }
7fe908 1517                         }
MC 1518                         $rewrite_rules[] = array( 'rewrite_domain'  => 'www.'.$alias['domain'],
1519                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'],
1520                             'rewrite_target'  => $alias['redirect_path'],
1521                             'rewrite_subdir' => $rewrite_subdir,
1522                             'proxy_directives' => $final_proxy_directives,
1523                             'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true),
1524                             'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false),
1525                             'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false));
1526                         break;
1527                     case '*':
1528                         if($alias['redirect_type'] == 'proxy'){
1529                             $tmp_redirect_path = $alias['redirect_path'];
1530                             $tmp_redirect_path_parts = parse_url($tmp_redirect_path);
1531                             $rewrite_subdir = $tmp_redirect_path_parts['path'];
1532                             if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1);
1533                             if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/';
1534                             if($rewrite_subdir == '/') $rewrite_subdir = '';
1535                         }
1536
1537                         if($alias['redirect_type'] != 'proxy'){
1538                             if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1);
1539                         }
1540                         // Add SEO redirects for alias domains
1541                         $alias_seo_redirects2 = array();
1542                         if($alias['seo_redirect'] != ''){
1543                             $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_');
1544                             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1545                                 $alias_seo_redirects2[] = $tmp_seo_redirects;
146783 1546                             }
7fe908 1547                         }
MC 1548                         $rewrite_rules[] = array( 'rewrite_domain'  => $alias['domain'].' *.'.$alias['domain'],
1549                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'],
1550                             'rewrite_target'  => $alias['redirect_path'],
1551                             'rewrite_subdir' => $rewrite_subdir,
1552                             'proxy_directives' => $final_proxy_directives,
1553                             'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true),
1554                             'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false),
1555                             'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false));
1556                         break;
1557                     default:
1558                         if($alias['redirect_type'] == 'proxy'){
1559                             $tmp_redirect_path = $alias['redirect_path'];
1560                             $tmp_redirect_path_parts = parse_url($tmp_redirect_path);
1561                             $rewrite_subdir = $tmp_redirect_path_parts['path'];
1562                             if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1);
1563                             if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/';
1564                             if($rewrite_subdir == '/') $rewrite_subdir = '';
1565                         }
1566
1567                         if($alias['redirect_type'] != 'proxy'){
1568                             if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1);
1569                         }
1570                         if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2);
1571                         else $domain_rule = $alias['domain'];
1572                         // Add SEO redirects for alias domains
1573                         $alias_seo_redirects2 = array();
1574                         if($alias['seo_redirect'] != ''){
1575                             if(substr($alias['domain'], 0, 2) === '*.'){
146783 1576                                 $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_');
7fe908 1577                             } else {
MC 1578                                 $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none');
146783 1579                             }
7fe908 1580                             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
MC 1581                                 $alias_seo_redirects2[] = $tmp_seo_redirects;
146783 1582                             }
7fe908 1583                         }
MC 1584                         $rewrite_rules[] = array( 'rewrite_domain'  => $domain_rule,
1585                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'],
1586                             'rewrite_target'  => $alias['redirect_path'],
1587                             'rewrite_subdir' => $rewrite_subdir,
1588                             'proxy_directives' => $final_proxy_directives,
1589                             'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true),
1590                             'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false),
1591                             'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false));
146783 1592                     }
MC 1593                 }
1594             }
1595         }
1596
1597         //* If we have some alias records
1598         if(count($server_alias) > 0) {
1599             $server_alias_str = '';
1600             $n = 0;
1601
1602             foreach($server_alias as $tmp_alias) {
1603                 $server_alias_str .= $tmp_alias;
1604             }
1605             unset($tmp_alias);
1606
7fe908 1607             $tpl->setVar('alias', trim($server_alias_str));
146783 1608         } else {
7fe908 1609             $tpl->setVar('alias', '');
146783 1610         }
MC 1611
1612         if(count($rewrite_rules) > 0) {
7fe908 1613             $tpl->setLoop('redirects', $rewrite_rules);
146783 1614         }
MC 1615         if(count($own_rewrite_rules) > 0) {
7fe908 1616             $tpl->setLoop('own_redirects', $own_rewrite_rules);
146783 1617         }
MC 1618         if(count($local_rewrite_rules) > 0) {
7fe908 1619             $tpl->setLoop('local_redirects', $local_rewrite_rules);
146783 1620         }
MC 1621         if(count($alias_seo_redirects) > 0) {
7fe908 1622             $tpl->setLoop('alias_seo_redirects', $alias_seo_redirects);
146783 1623         }
7fe908 1624
146783 1625         //* Create basic http auth for website statistics
MC 1626         $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/web/stats/.htpasswd_stats");
7fe908 1627
146783 1628         // Create basic http auth for other directories
MC 1629         $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']);
1630         if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations);
1631
1632         $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost');
1633         //* Make a backup copy of vhost file
7fe908 1634         if(file_exists($vhost_file)) copy($vhost_file, $vhost_file.'~');
MC 1635
146783 1636         //* Write vhost file
7fe908 1637         $app->system->file_put_contents($vhost_file, $this->nginx_merge_locations($tpl->grab()));
MC 1638         $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
146783 1639         unset($tpl);
MC 1640
1641         //* Set the symlink to enable the vhost
1642         //* First we check if there is a old type of symlink and remove it
1643         $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost');
1644         if(is_link($vhost_symlink)) unlink($vhost_symlink);
7fe908 1645
146783 1646         //* Remove old or changed symlinks
MC 1647         if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') {
1648             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1649             if(is_link($vhost_symlink)) {
1650                 $app->system->unlink($vhost_symlink);
7fe908 1651                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1652             }
MC 1653             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1654             if(is_link($vhost_symlink)) {
1655                 $app->system->unlink($vhost_symlink);
7fe908 1656                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1657             }
MC 1658         }
7fe908 1659
146783 1660         //* New symlink
MC 1661         if($data['new']['subdomain'] == '*') {
1662             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1663         } else {
1664             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1665         }
1666         if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) {
7fe908 1667             symlink($vhost_file, $vhost_symlink);
MC 1668             $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1669         }
MC 1670
1671         // remove old symlink and vhost file, if domain name of the site has changed
1672         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
1673             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
1674             if(is_link($vhost_symlink)) {
1675                 $app->system->unlink($vhost_symlink);
7fe908 1676                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1677             }
MC 1678             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1679             if(is_link($vhost_symlink)) {
1680                 $app->system->unlink($vhost_symlink);
7fe908 1681                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1682             }
MC 1683             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
1684             if(is_link($vhost_symlink)) {
1685                 $app->system->unlink($vhost_symlink);
7fe908 1686                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1687             }
MC 1688             $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
1689             $app->system->unlink($vhost_file);
7fe908 1690             $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG);
146783 1691         }
7fe908 1692
146783 1693         // create password file for stats directory
MC 1694         if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
1695             if(trim($data['new']['stats_password']) != '') {
1696                 $htp_file = 'admin:'.trim($data['new']['stats_password']);
7fe908 1697                 $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file);
MC 1698                 $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755);
146783 1699                 unset($htp_file);
MC 1700             }
1701         }
7fe908 1702
146783 1703         //* Create awstats configuration
511ba5 1704         if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) {
7fe908 1705             $this->awstats_update($data, $web_config);
146783 1706         }
7fe908 1707
MC 1708         $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir);
1c6da3 1709         $this->hhvm_update($data, $web_config);
7fe908 1710
146783 1711         if($web_config['check_apache_config'] == 'y') {
MC 1712             //* Test if nginx starts with the new configuration file
7fe908 1713             $nginx_online_status_before_restart = $this->_checkTcp('localhost', 80);
MC 1714             $app->log('nginx status is: '.($nginx_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
146783 1715
7fe908 1716             $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure
MC 1717             $app->log('nginx restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG);
1718
146783 1719             // wait a few seconds, before we test the apache status again
MC 1720             sleep(2);
7fe908 1721
146783 1722             //* Check if nginx restarted successfully if it was online before
7fe908 1723             $nginx_online_status_after_restart = $this->_checkTcp('localhost', 80);
MC 1724             $app->log('nginx online status after restart is: '.($nginx_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
1725             if($nginx_online_status_before_restart && !$nginx_online_status_after_restart || $retval['retval'] > 0) {
1726                 $app->log('nginx 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);
146783 1727                 if(is_array($retval['output']) && !empty($retval['output'])){
7fe908 1728                     $app->log('Reason for nginx restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN);
146783 1729                     $app->dbmaster->datalogError(implode("\n", $retval['output']));
MC 1730                 } else {
1731                     // if no output is given, check again
1732                     exec('nginx -t 2>&1', $tmp_output, $tmp_retval);
1733                     if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){
7fe908 1734                         $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN);
146783 1735                         $app->dbmaster->datalogError(implode("\n", $tmp_output));
MC 1736                     }
1737                     unset($tmp_output, $tmp_retval);
1738                 }
7fe908 1739                 $app->system->copy($vhost_file, $vhost_file.'.err');
MC 1740
146783 1741                 if(is_file($vhost_file.'~')) {
MC 1742                     //* Copy back the last backup file
7fe908 1743                     $app->system->copy($vhost_file.'~', $vhost_file);
146783 1744                 } else {
MC 1745                     //* There is no backup file, so we create a empty vhost file with a warning message inside
7fe908 1746                     $app->system->file_put_contents($vhost_file, "# nginx did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors.");
146783 1747                 }
7fe908 1748
146783 1749                 if($this->ssl_certificate_changed === true) {
MC 1750
1751                     $ssl_dir = $data['new']['document_root'].'/ssl';
1752                     $domain = $data['new']['ssl_domain'];
1753                     $key_file = $ssl_dir.'/'.$domain.'.key.org';
1754                     $key_file2 = $ssl_dir.'/'.$domain.'.key';
1755                     $csr_file = $ssl_dir.'/'.$domain.'.csr';
1756                     $crt_file = $ssl_dir.'/'.$domain.'.crt';
1757                     //$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
7fe908 1758
146783 1759                     //* Backup the files that might have caused the error
MC 1760                     if(is_file($key_file)){
7fe908 1761                         $app->system->copy($key_file, $key_file.'.err');
MC 1762                         $app->system->chmod($key_file.'.err', 0400);
146783 1763                     }
MC 1764                     if(is_file($key_file2)){
7fe908 1765                         $app->system->copy($key_file2, $key_file2.'.err');
MC 1766                         $app->system->chmod($key_file2.'.err', 0400);
146783 1767                     }
7fe908 1768                     if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err');
MC 1769                     if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err');
146783 1770                     //if(is_file($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'.err');
7fe908 1771
146783 1772                     //* Restore the ~ backup files
7fe908 1773                     if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file);
MC 1774                     if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2);
1775                     if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file);
1776                     if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file);
146783 1777                     //if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~',$bundle_file);
7fe908 1778
MC 1779                     $app->log('nginx 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);
146783 1780                 }
7fe908 1781
MC 1782                 $app->services->restartService('httpd', 'restart');
146783 1783             }
MC 1784         } else {
1785             //* We do not check the nginx config after changes (is faster)
7fe908 1786             $app->services->restartServiceDelayed('httpd', 'reload');
146783 1787         }
7fe908 1788
MC 1789         //* The vhost is written and apache has been restarted, so we
146783 1790         // can reset the ssl changed var to false and cleanup some files
MC 1791         $this->ssl_certificate_changed = false;
7fe908 1792
146783 1793         $ssl_dir = $data['new']['document_root'].'/ssl';
MC 1794         $domain = $data['new']['ssl_domain'];
1795         $key_file = $ssl_dir.'/'.$domain.'.key.org';
1796         $key_file2 = $ssl_dir.'/'.$domain.'.key';
1797         $csr_file = $ssl_dir.'/'.$domain.'.csr';
1798         $crt_file = $ssl_dir.'/'.$domain.'.crt';
1799         //$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
7fe908 1800
146783 1801         if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~');
MC 1802         if(@is_file($key2_file.'~')) $app->system->unlink($key2_file.'~');
1803         if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~');
1804         if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~');
1805         //if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~');
7fe908 1806
146783 1807         // Remove the backup copy of the config file.
MC 1808         if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~');
1809
1810         //* Unset action to clean it for next processed vhost.
1811         $this->action = '';
1812
1813     }
1814
7fe908 1815     function delete($event_name, $data) {
146783 1816         global $app, $conf;
MC 1817
1818         // load the server configuration options
1819         $app->uses('getconf');
1820         $app->uses('system');
1821         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
7fe908 1822
511ba5 1823         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false);
146783 1824
MC 1825         //* Check if this is a chrooted setup
1826         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
1827             $nginx_chrooted = true;
1828         } else {
1829             $nginx_chrooted = false;
1830         }
7fe908 1831
146783 1832         //* Remove the mounts
MC 1833         $log_folder = 'log';
7fe908 1834         $web_folder = '';
511ba5 1835         if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') {
2af58c 1836             $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
146783 1837             if($tmp['domain'] != ''){
MC 1838                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
1839             } else {
1840                 // get log folder from /etc/fstab
1841                 /*
1842                 $bind_mounts = $app->system->file_get_contents('/etc/fstab');
1843                 $bind_mount_lines = explode("\n", $bind_mounts);
1844                 if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){
1845                     foreach($bind_mount_lines as $bind_mount_line){
1846                         $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line);
1847                         $bind_mount_parts = explode(' ', $bind_mount_line);
1848                         if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){
1849                             if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){
1850                                 $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]);
1851                             }
1852                         }
1853                     }
1854                 }
1855                 */
1856                 // we are deleting the parent domain, so we can delete everything in the log directory
1857                 $subdomain_hosts = array();
7fe908 1858                 $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..'));
146783 1859                 if(is_array($files) && !empty($files)){
MC 1860                     foreach($files as $file){
1861                         if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){
1862                             $subdomain_hosts[] = $file;
1863                         }
1864                     }
1865                 }
1866             }
1867             if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){
1868                 $log_folders = array();
1869                 foreach($subdomain_hosts as $subdomain_host){
1870                     $log_folders[] = $log_folder.'/'.$subdomain_host;
1871                 }
1872             } else {
1873                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
1874                 $log_folder .= '/' . $subdomain_host;
1875             }
1876             $web_folder = $data['old']['web_folder'];
7fe908 1877             unset($tmp);
146783 1878             unset($subdomain_hosts);
MC 1879         }
7fe908 1880
511ba5 1881         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){
146783 1882             if(is_array($log_folders) && !empty($log_folders)){
MC 1883                 foreach($log_folders as $log_folder){
1884                     //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
a9b325 1885                     //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
146783 1886                     exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
MC 1887                 }
1888             } else {
1889                 //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
a9b325 1890                 //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
146783 1891                 exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
MC 1892             }
1893         }
7fe908 1894
146783 1895         //* remove mountpoint from fstab
MC 1896         if(is_array($log_folders) && !empty($log_folders)){
1897             foreach($log_folders as $log_folder){
1898                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
7fe908 1899                 $app->system->removeLine('/etc/fstab', $fstab_line);
146783 1900             }
MC 1901         } else {
1902             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
7fe908 1903             $app->system->removeLine('/etc/fstab', $fstab_line);
146783 1904         }
MC 1905         unset($log_folders);
1906
511ba5 1907         if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) {
146783 1908             //* This is a alias domain or subdomain, so we have to update the website instead
MC 1909             $parent_domain_id = intval($data['old']['parent_domain_id']);
2af58c 1910             $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id);
146783 1911             $data['new'] = $tmp;
MC 1912             $data['old'] = $tmp;
1913             $this->action = 'update';
1914             // just run the update function
7fe908 1915             $this->update($event_name, $data);
146783 1916
MC 1917         } else {
1918             //* This is a website
7fe908 1919             // Deleting the vhost file, symlink and the data directory
146783 1920             $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
7fe908 1921
146783 1922             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
MC 1923             if(is_link($vhost_symlink)){
1924                 $app->system->unlink($vhost_symlink);
7fe908 1925                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1926             }
MC 1927             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
1928             if(is_link($vhost_symlink)){
1929                 $app->system->unlink($vhost_symlink);
7fe908 1930                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1931             }
MC 1932             $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1933             if(is_link($vhost_symlink)){
1934                 $app->system->unlink($vhost_symlink);
7fe908 1935                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
146783 1936             }
7fe908 1937
146783 1938             $app->system->unlink($vhost_file);
7fe908 1939             $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
146783 1940
511ba5 1941             if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') {
7fe908 1942                 $docroot = escapeshellcmd($data['old']['document_root']);
MC 1943                 if($docroot != '' && !stristr($docroot, '..')) {
1944                     if($data['old']['type'] == 'vhost') {
1945                         // this is a vhost - we delete everything in here.
1946                         exec('rm -rf '.$docroot);
1947                     } elseif(!stristr($data['old']['web_folder'], '..')) {
1948                         // this is a vhost subdomain
1949                         // IMPORTANT: do some folder checks before we delete this!
1950                         $do_delete = true;
1951                         $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times
1952                         if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1);
1953                         if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1);
146783 1954
7fe908 1955                         $path_elements = explode('/', $delete_folder);
146783 1956
7fe908 1957                         if($path_elements[0] == 'web' || $path_elements[0] === '') {
MC 1958                             // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here!
1959                             // we use strict check as otherwise directories named '0' may not be deleted
1960                             $do_delete = false;
1961                         } else {
1962                             // read all vhost subdomains with same parent domain
1963                             $used_paths = array();
2af58c 1964                             $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']);
7fe908 1965                             foreach($tmp as $tmprec) {
MC 1966                                 // we normalize the folder entries because we need to compare them
1967                                 $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times
1968                                 if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1);
1969                                 if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1);
146783 1970
7fe908 1971                                 // add this path and it's parent paths to used_paths array
MC 1972                                 while(strpos($tmp_folder, '/') !== false) {
1973                                     if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1974                                     $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/'));
1975                                 }
1976                                 if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1977                             }
1978                             unset($tmp);
146783 1979
7fe908 1980                             // loop and check if the path is still used and stop at first used one
MC 1981                             // set do_delete to false so nothing gets deleted if the web_folder itself is still used
1982                             $do_delete = false;
1983                             while(count($path_elements) > 0) {
1984                                 $tmp_folder = implode('/', $path_elements);
1985                                 if(in_array($tmp_folder, $used_paths) == true) break;
1986
1987                                 // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true
1988                                 $delete_folder = $tmp_folder;
1989                                 $do_delete = true;
1990                                 array_pop($path_elements);
1991                             }
1992                             unset($tmp_folder);
1993                             unset($used_paths);
1994                         }
1995
1996                         if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder);
1997
1998                         unset($delete_folder);
1999                         unset($path_elements);
2000                     }
2001                 }
2002
2003                 //remove the php fastgi starter script if available
2004                 if ($data['old']['php'] == 'fast-cgi') {
2005                     $this->php_fpm_pool_delete($data, $web_config);
2006                     $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['fastcgi_starter_path']);
2007                     if($data['old']['type'] == 'vhost') {
2008                         if (is_dir($fastcgi_starter_path)) {
2009                             exec('rm -rf '.$fastcgi_starter_path);
2010                         }
2011                     } else {
2012                         $fcgi_starter_script = $fastcgi_starter_path.$web_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id'];
2013                         if (file_exists($fcgi_starter_script)) {
2014                             exec('rm -f '.$fcgi_starter_script);
2015                         }
2016                     }
2017                 }
2018
2019                 // remove PHP-FPM pool
2020                 if ($data['old']['php'] == 'php-fpm') {
2021                     $this->php_fpm_pool_delete($data, $web_config);
1c6da3 2022                 } elseif($data['old']['php'] == 'hhvm') {
MC 2023                     $this->hhvm_update($data, $web_config);
7fe908 2024                 }
MC 2025
2026                 //remove the php cgi starter script if available
2027                 if ($data['old']['php'] == 'cgi') {
2028                     // TODO: fetch the date from the server-settings
2029                     $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
2030
2031                     $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']);
2032                     if($data['old']['type'] == 'vhost') {
2033                         if (is_dir($cgi_starter_path)) {
2034                             exec('rm -rf '.$cgi_starter_path);
2035                         }
2036                     } else {
2037                         $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id'];
2038                         if (file_exists($cgi_starter_script)) {
2039                             exec('rm -f '.$cgi_starter_script);
2040                         }
2041                     }
2042                 }
2043
2044                 $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG);
2045
2046                 // Delete the symlinks for the sites
2af58c 2047                 $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']);
7fe908 2048                 $client_id = intval($client['client_id']);
MC 2049                 unset($client);
2050                 $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
2051                 if(is_array($tmp_symlinks_array)) {
2052                     foreach($tmp_symlinks_array as $tmp_symlink) {
2053                         $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
2054                         $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
2055                         // Remove trailing slash
2056                         if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
2057                         // create the symlinks, if not exist
2058                         if(is_link($tmp_symlink)) {
2059                             $app->system->unlink($tmp_symlink);
2060                             $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG);
2061                         }
2062                     }
2063                 }
2064                 // end removing symlinks
2065             } else {
2066                 // vhost subdomain
146783 2067             }
7fe908 2068
MC 2069             // Delete the log file directory
2070             $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']);
2071             if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir);
2072             $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG);
2073
2074             if($data['old']['type'] == 'vhost') {
2075                 //delete the web user
2076                 $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel';
2077                 $command .= ' '.escapeshellcmd($data['old']['system_user']);
2078                 exec($command);
2079                 if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
2080
2081             }
2082
2083             //* Remove the awstats configuration file
2084             if($data['old']['stats_type'] == 'awstats') {
2085                 $this->awstats_delete($data, $web_config);
2086             }
2087
990ca8 2088             //* Delete the web-backups
FS 2089             if($data['old']['type'] == 'vhost') {
2090                 $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
2091                 $backup_dir = $server_config['backup_dir'];
2092                 $mount_backup = true;
2093                 if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') {
2094                     //* mount backup directory, if necessary
2095                     if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false;
2096                     if($mount_backup){
2097                         $web_backup_dir = $backup_dir.'/web'.$data_old['domain_id'];
2098                         //** do not use rm -rf $web_backup_dir because database(s) may exits
2099                         exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*');
2100                         //* cleanup database
2101                         $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?";
2102                         $app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%");
2103                         if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%");
2104
2105                         $app->log('Deleted the web backup files', LOGLEVEL_DEBUG);
2106                     }
2107                 }
2108             }
2109
7fe908 2110             $app->services->restartServiceDelayed('httpd', 'reload');
146783 2111
MC 2112         }
7fe908 2113
MC 2114
2115         if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true);
146783 2116     }
MC 2117
2118     //* This function is called when a IP on the server is inserted, updated or deleted
7fe908 2119     function server_ip($event_name, $data) {
146783 2120         return;
MC 2121     }
7fe908 2122
146783 2123     //* Create or update the .htaccess folder protection
7fe908 2124     function web_folder_user($event_name, $data) {
146783 2125         global $app, $conf;
MC 2126
2127         $app->uses('system');
7fe908 2128
146783 2129         if($event_name == 'web_folder_user_delete') {
MC 2130             $folder_id = $data['old']['web_folder_id'];
2131         } else {
2132             $folder_id = $data['new']['web_folder_id'];
2133         }
7fe908 2134
2af58c 2135         $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id);
MC 2136         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']);
7fe908 2137
146783 2138         if(!is_array($folder) or !is_array($website)) {
7fe908 2139             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
146783 2140             return false;
MC 2141         }
7fe908 2142
MC 2143         $web_folder = 'web';
511ba5 2144         if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
7fe908 2145
146783 2146         //* Get the folder path.
7fe908 2147         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2148         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
146783 2149         $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
7fe908 2150         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2151
146783 2152         //* Check if the resulting path is inside the docroot
7fe908 2153         if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) {
MC 2154             $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
146783 2155             return false;
MC 2156         }
7fe908 2157
146783 2158         //* Create the folder path, if it does not exist
MC 2159         if(!is_dir($folder_path)) {
dbae22 2160             $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']);
146783 2161         }
7fe908 2162
146783 2163         //* Create empty .htpasswd file, if it does not exist
MC 2164         if(!is_file($folder_path.'.htpasswd')) {
2165             touch($folder_path.'.htpasswd');
7fe908 2166             $app->system->chmod($folder_path.'.htpasswd', 0755);
MC 2167             $app->system->chown($folder_path.'.htpasswd', $website['system_user']);
2168             $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']);
2169             $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
146783 2170         }
7fe908 2171
146783 2172         if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
7fe908 2173             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2174             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
146783 2175         }
7fe908 2176
146783 2177         //* Add or remove the user from .htpasswd file
MC 2178         if($event_name == 'web_folder_user_delete') {
7fe908 2179             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2180             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
146783 2181         } else {
MC 2182             if($data['new']['active'] == 'y') {
7fe908 2183                 $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1);
MC 2184                 $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG);
146783 2185             }
MC 2186         }
7fe908 2187
146783 2188         // write basic auth configuration to vhost file because nginx does not support .htaccess
MC 2189         $webdata['new'] = $webdata['old'] = $website;
2190         $this->update('web_domain_update', $webdata);
2191     }
7fe908 2192
146783 2193     //* Remove .htpasswd file, when folder protection is removed
7fe908 2194     function web_folder_delete($event_name, $data) {
146783 2195         global $app, $conf;
7fe908 2196
146783 2197         $folder_id = $data['old']['web_folder_id'];
7fe908 2198
146783 2199         $folder = $data['old'];
2af58c 2200         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']);
7fe908 2201
146783 2202         if(!is_array($folder) or !is_array($website)) {
7fe908 2203             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
146783 2204             return false;
MC 2205         }
7fe908 2206
MC 2207         $web_folder = 'web';
511ba5 2208         if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
7fe908 2209
146783 2210         //* Get the folder path.
7fe908 2211         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2212         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
146783 2213         $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
7fe908 2214         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2215
146783 2216         //* Check if the resulting path is inside the docroot
7fe908 2217         if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2218             $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG);
146783 2219             return false;
MC 2220         }
7fe908 2221
146783 2222         //* Remove .htpasswd file
MC 2223         if(is_file($folder_path.'.htpasswd')) {
2224             $app->system->unlink($folder_path.'.htpasswd');
7fe908 2225             $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
146783 2226         }
7fe908 2227
146783 2228         // write basic auth configuration to vhost file because nginx does not support .htaccess
MC 2229         $webdata['new'] = $webdata['old'] = $website;
2230         $this->update('web_domain_update', $webdata);
2231     }
7fe908 2232
146783 2233     //* Update folder protection, when path has been changed
7fe908 2234     function web_folder_update($event_name, $data) {
146783 2235         global $app, $conf;
7fe908 2236
2af58c 2237         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
7fe908 2238
146783 2239         if(!is_array($website)) {
7fe908 2240             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
146783 2241             return false;
MC 2242         }
7fe908 2243
MC 2244         $web_folder = 'web';
511ba5 2245         if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
7fe908 2246
146783 2247         //* Get the folder path.
7fe908 2248         if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1);
MC 2249         if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1);
146783 2250         $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']);
7fe908 2251         if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/';
MC 2252
2253         if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1);
2254         if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1);
146783 2255         $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']);
7fe908 2256         if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/';
MC 2257
146783 2258         //* Check if the resulting path is inside the docroot
7fe908 2259         if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) {
MC 2260             $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
146783 2261             return false;
MC 2262         }
7fe908 2263         if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) {
MC 2264             $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
146783 2265             return false;
MC 2266         }
7fe908 2267
146783 2268         //* Check if the resulting path is inside the docroot
7fe908 2269         if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2270             $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
146783 2271             return false;
MC 2272         }
7fe908 2273         if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2274             $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
146783 2275             return false;
MC 2276         }
7fe908 2277
146783 2278         //* Create the folder path, if it does not exist
MC 2279         if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path);
7fe908 2280
146783 2281         if($data['old']['path'] != $data['new']['path']) {
MC 2282
7fe908 2283
146783 2284             //* move .htpasswd file
MC 2285             if(is_file($old_folder_path.'.htpasswd')) {
7fe908 2286                 $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd');
MC 2287                 $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
146783 2288             }
7fe908 2289
146783 2290         }
MC 2291
2292         // write basic auth configuration to vhost file because nginx does not support .htaccess
2293         $webdata['new'] = $webdata['old'] = $website;
2294         $this->update('web_domain_update', $webdata);
2295     }
7fe908 2296
146783 2297     function _create_web_folder_auth_configuration($website){
MC 2298         global $app, $conf;
2299         //* Create the domain.auth file which is included in the vhost configuration file
2300         $app->uses('getconf');
2301         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
2302         $basic_auth_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$website['domain'].'.auth');
2303         //$app->load('tpl');
2304         //$tpl = new tpl();
2305         //$tpl->newTemplate('nginx_http_authentication.auth.master');
2af58c 2306         $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ?", $website['domain_id']);
146783 2307         $basic_auth_locations = array();
MC 2308         if(is_array($website_auth_locations) && !empty($website_auth_locations)){
2309             foreach($website_auth_locations as $website_auth_location){
7fe908 2310                 if(substr($website_auth_location['path'], 0, 1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 1);
MC 2311                 if(substr($website_auth_location['path'], -1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 0, -1);
146783 2312                 if($website_auth_location['path'] != ''){
MC 2313                     $website_auth_location['path'] .= '/';
2314                 }
2315                 $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'],
511ba5 2316                     'htpasswd_path' => $website['document_root'].'/' . (($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']);
146783 2317             }
MC 2318         }
2319         return $basic_auth_locations;
2320         //$tpl->setLoop('basic_auth_locations', $basic_auth_locations);
2321         //file_put_contents($basic_auth_file,$tpl->grab());
2322         //$app->log('Writing the http basic authentication file: '.$basic_auth_file,LOGLEVEL_DEBUG);
2323         //unset($tpl);
2324         //$app->services->restartServiceDelayed('httpd','reload');
2325     }
7fe908 2326
146783 2327     //* Update the awstats configuration file
7fe908 2328     private function awstats_update ($data, $web_config) {
146783 2329         global $app;
7fe908 2330
MC 2331         $web_folder = $data['new']['web_folder'];
2332         if($data['new']['type'] == 'vhost') $web_folder = 'web';
146783 2333         $awstats_conf_dir = $web_config['awstats_conf_dir'];
7fe908 2334
146783 2335         if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats");
MC 2336         if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) {
2337             if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
2338                 $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
2339             }
7fe908 2340
146783 2341             $content = '';
e6abfe 2342             if (is_file($awstats_conf_dir."/awstats.conf")) {
CS 2343                 $include_file = $awstats_conf_dir."/awstats.conf";
2344             } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) {
2345                 $include_file = $awstats_conf_dir."/awstats.model.conf";
2346             }
de6d2e 2347             $content .= "Include \"".$include_file."\"\n";
146783 2348             $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n";
MC 2349             $content .= "SiteDomain=\"".$data['new']['domain']."\"\n";
2350             $content .= "HostAliases=\"www.".$data['new']['domain']."  localhost 127.0.0.1\"\n";
7fe908 2351
9aaf97 2352             if (isset($include_file)) {
CS 2353                 $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content);
2354                 $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG);
2355             } else {
2356                 $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN);
2357             }
146783 2358         }
7fe908 2359
146783 2360         if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html");
MC 2361         if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) {
7fe908 2362             $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
146783 2363         } else {
7fe908 2364             $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
146783 2365         }
MC 2366     }
7fe908 2367
146783 2368     //* Delete the awstats configuration file
7fe908 2369     private function awstats_delete ($data, $web_config) {
146783 2370         global $app;
7fe908 2371
146783 2372         $awstats_conf_dir = $web_config['awstats_conf_dir'];
7fe908 2373
146783 2374         if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
MC 2375             $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
7fe908 2376             $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG);
146783 2377         }
MC 2378     }
7fe908 2379
1c6da3 2380     private function hhvm_update($data, $web_config) {
MC 2381         global $app, $conf;
2382         
2383         if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_starter.master')) {
2384             $content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_starter.master');
2385         } else {
2386             $content = file_get_contents($conf['rootpath'] . '/conf/hhvm_starter.master');
2387         }
cab08c 2388         if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_monit.master')) {
MC 2389             $monit_content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_monit.master');
2390         } else {
2391             $monit_content = file_get_contents($conf['rootpath'] . '/conf/hhvm_monit.master');
2392         }
1c6da3 2393         
d5f2d5 2394         if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || $data['new']['custom_php_ini'] != $data['old']['custom_php_ini']) {
MC 2395
2396             // Custom php.ini settings
2397             $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
2398             if(intval($data['new']['directive_snippets_id']) > 0){
2399                 $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
2400                 if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
2401                     $required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
2402                     if(is_array($required_php_snippets) && !empty($required_php_snippets)){
2403                         foreach($required_php_snippets as $required_php_snippet){
2404                             $required_php_snippet = intval($required_php_snippet);
2405                             if($required_php_snippet > 0){
2406                                 $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
2407                                 $php_snippet['snippet'] = trim($php_snippet['snippet']);
2408                                 if($php_snippet['snippet'] != ''){
2409                                     $custom_php_ini_settings .= "\n".$php_snippet['snippet'];
2410                                 }
2411                             }
2412                         }
2413                     }
2414                 }
2415             }
2416             if($custom_php_ini_settings != ''){
2417                 // Make sure we only have Unix linebreaks
2418                 $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
2419                 $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
2420                 file_put_contents('/etc/hhvm/'.$data['new']['system_user'].'.ini', $custom_php_ini_settings);
2421             } else {
2422                 if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
2423             }
2424         
1c6da3 2425             $content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $content);
MC 2426             file_put_contents('/etc/init.d/hhvm_' . $data['new']['system_user'], $content);
2427             exec('chmod +x /etc/init.d/hhvm_' . $data['new']['system_user'] . ' >/dev/null 2>&1');
2428             exec('/usr/sbin/update-rc.d hhvm_' . $data['new']['system_user'] . ' defaults >/dev/null 2>&1');
d5f2d5 2429             exec('/etc/init.d/hhvm_' . $data['new']['system_user'] . ' restart >/dev/null 2>&1');
cab08c 2430             
02e7ea 2431             if(is_dir('/etc/monit/conf.d')){
MC 2432                 $monit_content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $monit_content);
2433                 file_put_contents('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'], $monit_content);
2434                 if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])) unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']);
2435                 exec('/etc/init.d/monit restart >/dev/null 2>&1');
2436             }
cab08c 2437             
1c6da3 2438          } elseif($data['new']['php'] != 'hhvm' && $data['old']['php'] == 'hhvm') {
MC 2439             exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1');
2440             exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1');
e956ac 2441             unlink('/etc/init.d/hhvm_' . $data['old']['system_user']);
d5f2d5 2442             if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
cab08c 2443             
02e7ea 2444             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 2445                 if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])){
2446                     unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']);
2447                 }
2448                 if(is_file('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'])){
2449                     unlink('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user']);
2450                 }
cab08c 2451                 exec('/etc/init.d/monit restart >/dev/null 2>&1');
MC 2452             }
1c6da3 2453         }
MC 2454     }
2455
146783 2456     //* Update the PHP-FPM pool configuration file
7fe908 2457     private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) {
146783 2458         global $app, $conf;
ab79c2 2459         $pool_dir = trim($pool_dir);
146783 2460         /*
MC 2461         if(trim($data['new']['fastcgi_php_version']) != ''){
2462             $default_php_fpm = false;
2463             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']));
2464             if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
2465         } else {
2466             $default_php_fpm = true;
2467         }
2468         */
02e7ea 2469         if($data['new']['php'] == 'php-fpm'){
146783 2470             if(trim($data['new']['fastcgi_php_version']) != ''){
MC 2471                 $default_php_fpm = false;
2472                 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']));
7fe908 2473                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
146783 2474             } else {
MC 2475                 $default_php_fpm = true;
2476             }
2477         } else {
2478             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){
2479                 $default_php_fpm = false;
2480                 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']));
7fe908 2481                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
146783 2482             } else {
MC 2483                 $default_php_fpm = true;
2484             }
2485         }
7fe908 2486
146783 2487         $app->uses("getconf");
MC 2488         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
7fe908 2489
02e7ea 2490         if($data['new']['php'] != 'php-fpm'){
146783 2491             if(@is_file($pool_dir.$pool_name.'.conf')){
MC 2492                 $app->system->unlink($pool_dir.$pool_name.'.conf');
2493                 //$reload = true;
2494             }
2495             if($data['old']['php'] != 'no'){
2496                 if(!$default_php_fpm){
7fe908 2497                     $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
146783 2498                 } else {
7fe908 2499                     $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
146783 2500                 }
MC 2501             }
2502             return;
2503         }
7fe908 2504
146783 2505         $app->load('tpl');
MC 2506         $tpl = new tpl();
2507         $tpl->newTemplate('php_fpm_pool.conf.master');
2508
2509         if($data['new']['php_fpm_use_socket'] == 'y'){
2510             $use_tcp = 0;
2511             $use_socket = 1;
2512             if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir);
2513         } else {
2514             $use_tcp = 1;
2515             $use_socket = 0;
2516         }
2517         $tpl->setVar('use_tcp', $use_tcp);
2518         $tpl->setVar('use_socket', $use_socket);
7fe908 2519
146783 2520         $fpm_socket = $socket_dir.$pool_name.'.sock';
MC 2521         $tpl->setVar('fpm_socket', $fpm_socket);
1890ca 2522         $tpl->setVar('fpm_listen_mode', '0660');
7fe908 2523
146783 2524         $tpl->setVar('fpm_pool', $pool_name);
MC 2525         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
2526         $tpl->setVar('fpm_user', $data['new']['system_user']);
2527         $tpl->setVar('fpm_group', $data['new']['system_group']);
2528         $tpl->setVar('pm', $data['new']['pm']);
2529         $tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
2530         $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']);
2531         $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']);
2532         $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']);
2533         $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']);
2534         $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']);
2535         $tpl->setVar('document_root', $data['new']['document_root']);
7fe908 2536         $tpl->setVar('security_level', $web_config['security_level']);
f63910 2537         $tpl->setVar('domain', $data['new']['domain']);
146783 2538         $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']);
MC 2539         $tpl->setVar('php_open_basedir', $php_open_basedir);
2540         if($php_open_basedir != ''){
2541             $tpl->setVar('enable_php_open_basedir', '');
2542         } else {
2543             $tpl->setVar('enable_php_open_basedir', ';');
2544         }
7fe908 2545
146783 2546         // Custom php.ini settings
MC 2547         $final_php_ini_settings = array();
2548         $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
b41803 2549         
MC 2550         if(intval($data['new']['directive_snippets_id']) > 0){
2551             $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
2552             if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
2553                 $required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
2554                 if(is_array($required_php_snippets) && !empty($required_php_snippets)){
2555                     foreach($required_php_snippets as $required_php_snippet){
2556                         $required_php_snippet = intval($required_php_snippet);
2557                         if($required_php_snippet > 0){
2558                             $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
2559                             $php_snippet['snippet'] = trim($php_snippet['snippet']);
2560                             if($php_snippet['snippet'] != ''){
2561                                 $custom_php_ini_settings .= "\n".$php_snippet['snippet'];
2562                             }
2563                         }
2564                     }
2565                 }
2566             }
2567         }
2568         
146783 2569         if($custom_php_ini_settings != ''){
MC 2570             // Make sure we only have Unix linebreaks
2571             $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
2572             $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
2573             $ini_settings = explode("\n", $custom_php_ini_settings);
2574             if(is_array($ini_settings) && !empty($ini_settings)){
2575                 foreach($ini_settings as $ini_setting){
2576                     $ini_setting = trim($ini_setting);
7fe908 2577                     if(substr($ini_setting, 0, 1) == ';') continue;
MC 2578                     if(substr($ini_setting, 0, 1) == '#') continue;
2579                     if(substr($ini_setting, 0, 2) == '//') continue;
03cc01 2580                     list($key, $value) = explode('=', $ini_setting, 2);
1d6097 2581                     $value = trim($value);
FT 2582                     if($value != ''){
146783 2583                         $key = trim($key);
MC 2584                         switch (strtolower($value)) {
7fe908 2585                         case '0':
MC 2586                             // PHP-FPM might complain about invalid boolean value if you use 0
2587                             $value = 'off';
2588                         case '1':
2589                         case 'on':
2590                         case 'off':
2591                         case 'true':
2592                         case 'false':
2593                         case 'yes':
2594                         case 'no':
2595                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value);
2596                             break;
2597                         default:
2598                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value);
146783 2599                         }
MC 2600                     }
2601                 }
2602             }
2603         }
7fe908 2604
146783 2605         $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
7fe908 2606
MC 2607         $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab());
2608         $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
146783 2609         unset($tpl);
7fe908 2610
146783 2611         // delete pool in all other PHP versions
ab79c2 2612         $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir']));
7fe908 2613         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
146783 2614         if($default_pool_dir != $pool_dir){
MC 2615             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
7fe908 2616                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 2617                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
2618                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
146783 2619             }
MC 2620         }
2af58c 2621         $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"]);
146783 2622         if(is_array($php_versions) && !empty($php_versions)){
MC 2623             foreach($php_versions as $php_version){
ab79c2 2624                 $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']);
7fe908 2625                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
146783 2626                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
MC 2627                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
2628                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
7fe908 2629                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2630                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
146783 2631                     }
MC 2632                 }
2633             }
2634         }
2635         // Reload current PHP-FPM after all others
2636         sleep(1);
2637         if(!$default_php_fpm){
7fe908 2638             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
146783 2639         } else {
7fe908 2640             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
146783 2641         }
MC 2642     }
7fe908 2643
146783 2644     //* Delete the PHP-FPM pool configuration file
7fe908 2645     private function php_fpm_pool_delete ($data, $web_config) {
146783 2646         global $app, $conf;
7fe908 2647
146783 2648         if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){
MC 2649             $default_php_fpm = false;
2650             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']));
7fe908 2651             if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
146783 2652         } else {
MC 2653             $default_php_fpm = true;
2654         }
7fe908 2655
146783 2656         if($default_php_fpm){
MC 2657             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
2658         } else {
2659             $pool_dir = $custom_php_fpm_pool_dir;
2660         }
ab79c2 2661         $pool_dir = trim($pool_dir);
7fe908 2662
MC 2663         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
146783 2664         $pool_name = 'web'.$data['old']['domain_id'];
7fe908 2665
146783 2666         if ( @is_file($pool_dir.$pool_name.'.conf') ) {
MC 2667             $app->system->unlink($pool_dir.$pool_name.'.conf');
7fe908 2668             $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
146783 2669         }
7fe908 2670
146783 2671         // delete pool in all other PHP versions
ab79c2 2672         $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir']));
7fe908 2673         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
146783 2674         if($default_pool_dir != $pool_dir){
MC 2675             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
7fe908 2676                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 2677                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
2678                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
146783 2679             }
7fe908 2680         }
2af58c 2681         $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']);
146783 2682         if(is_array($php_versions) && !empty($php_versions)){
MC 2683             foreach($php_versions as $php_version){
ab79c2 2684                 $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']);
7fe908 2685                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
146783 2686                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
MC 2687                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
2688                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
7fe908 2689                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2690                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
146783 2691                     }
MC 2692                 }
2693             }
2694         }
7fe908 2695
146783 2696         // Reload current PHP-FPM after all others
MC 2697         sleep(1);
2698         if(!$default_php_fpm){
7fe908 2699             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
146783 2700         } else {
7fe908 2701             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
146783 2702         }
MC 2703     }
7fe908 2704
146783 2705     private function nginx_replace($matches){
MC 2706         $location = 'location'.($matches[1] != '' ? ' '.$matches[1] : '').' '.$matches[2].' '.$matches[3];
2707         if($matches[4] == '##merge##' || $matches[7] == '##merge##') $location .= ' ##merge##';
2708         if($matches[4] == '##delete##' || $matches[7] == '##delete##') $location .= ' ##delete##';
2709         $location .= "\n";
2710         $location .= $matches[5]."\n";
2711         $location .= $matches[6];
2712         return $location;
2713     }
7fe908 2714
146783 2715     private function nginx_merge_locations($vhost_conf){
MC 2716
2717         $lines = explode("\n", $vhost_conf);
7fe908 2718
146783 2719         // if whole location block is in one line, split it up into multiple lines
MC 2720         if(is_array($lines) && !empty($lines)){
2721             $linecount = sizeof($lines);
2722             for($h=0;$h<$linecount;$h++){
2723                 // remove comments
7fe908 2724                 if(substr(trim($lines[$h]), 0, 1) == '#'){
146783 2725                     unset($lines[$h]);
MC 2726                     continue;
2727                 }
7fe908 2728
146783 2729                 $lines[$h] = rtrim($lines[$h]);
MC 2730                 /*
2731                 if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], ';') !== false){
2732                     $lines[$h] = str_replace("{", "{\n", $lines[$h]);
2733                     $lines[$h] = str_replace(";", ";\n", $lines[$h]);
2734                     if(strpos($lines[$h], '##merge##') !== false){
2735                         $lines[$h] = str_replace('##merge##', '', $lines[$h]);
2736                         $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1);
2737                     }
2738                 }
2739                 if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], '}') !== false && strpos($lines[$h], ';') === false){
2740                     $lines[$h] = str_replace("{", "{\n", $lines[$h]);
2741                     if(strpos($lines[$h], '##merge##') !== false){
2742                         $lines[$h] = str_replace('##merge##', '', $lines[$h]);
2743                         $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1);
2744                     }
2745                 }
2746                 */
2747                 $pattern = '/^[^\S\n]*location[^\S\n]+(?:(.+)[^\S\n]+)?(.+)[^\S\n]*(\{)[^\S\n]*(##merge##|##delete##)?[^\S\n]*(.+)[^\S\n]*(\})[^\S\n]*(##merge##|##delete##)?[^\S\n]*$/';
7fe908 2748                 $lines[$h] = preg_replace_callback($pattern, array($this, 'nginx_replace') , $lines[$h]);
146783 2749             }
MC 2750         }
2751         $vhost_conf = implode("\n", $lines);
2752         unset($lines);
2753         unset($linecount);
7fe908 2754
146783 2755         $lines = explode("\n", $vhost_conf);
7fe908 2756
MC 2757         if(is_array($lines) && !empty($lines)){
146783 2758             $locations = array();
MC 2759             $locations_to_delete = array();
2760             $islocation = false;
2761             $linecount = sizeof($lines);
2762             $server_count = 0;
2763
2764             for($i=0;$i<$linecount;$i++){
2765                 $l = trim($lines[$i]);
2766                 if(substr($l, 0, 8) == 'server {') $server_count += 1;
2767                 if($server_count > 1) break;
2768                 if(substr($l, 0, 8) == 'location' && !$islocation){
7fe908 2769
146783 2770                     $islocation = true;
MC 2771                     $level = 0;
7fe908 2772
146783 2773                     // Remove unnecessary whitespace
MC 2774                     $l = preg_replace('/\s\s+/', ' ', $l);
7fe908 2775
146783 2776                     $loc_parts = explode(' ', $l);
MC 2777                     // see http://wiki.nginx.org/HttpCoreModule#location
2778                     if($loc_parts[1] == '=' || $loc_parts[1] == '~' || $loc_parts[1] == '~*' || $loc_parts[1] == '^~'){
2779                         $location = $loc_parts[1].' '.$loc_parts[2];
2780                     } else {
2781                         $location = $loc_parts[1];
2782                     }
2783                     unset($loc_parts);
7fe908 2784
146783 2785                     if(!isset($locations[$location]['action'])) $locations[$location]['action'] = 'replace';
MC 2786                     if(substr($l, -9) == '##merge##') $locations[$location]['action'] = 'merge';
2787                     if(substr($l, -10) == '##delete##') $locations[$location]['action'] = 'delete';
7fe908 2788
146783 2789                     if(!isset($locations[$location]['open_tag'])) $locations[$location]['open_tag'] = '        location '.$location.' {';
MC 2790                     if(!isset($locations[$location]['location']) || $locations[$location]['action'] == 'replace') $locations[$location]['location'] = '';
2791                     if($locations[$location]['action'] == 'delete') $locations_to_delete[] = $location;
2792                     if(!isset($locations[$location]['end_tag'])) $locations[$location]['end_tag'] = '        }';
2793                     if(!isset($locations[$location]['start_line'])) $locations[$location]['start_line'] = $i;
2794
2795                     unset($lines[$i]);
7fe908 2796
146783 2797                 } else {
7fe908 2798
146783 2799                     if($islocation){
MC 2800                         if(strpos($l, '{') !== false){
2801                             $level += 1;
2802                         }
2803                         if(strpos($l, '}') !== false && $level > 0){
2804                             $level -= 1;
2805                             $locations[$location]['location'] .= $lines[$i]."\n";
2806                         } elseif(strpos($l, '}') !== false && $level == 0){
2807                             $islocation = false;
2808                         } else {
2809                             $locations[$location]['location'] .= $lines[$i]."\n";
2810                         }
2811                         unset($lines[$i]);
2812                     }
7fe908 2813
146783 2814                 }
MC 2815             }
7fe908 2816
146783 2817             if(is_array($locations) && !empty($locations)){
MC 2818                 if(is_array($locations_to_delete) && !empty($locations_to_delete)){
2819                     foreach($locations_to_delete as $location_to_delete){
2820                         if(isset($locations[$location_to_delete])) unset($locations[$location_to_delete]);
2821                     }
2822                 }
7fe908 2823
146783 2824                 foreach($locations as $key => $val){
MC 2825                     $new_location = $val['open_tag']."\n".$val['location'].$val['end_tag'];
2826                     $lines[$val['start_line']] = $new_location;
2827                 }
2828             }
2829             ksort($lines);
2830             $vhost_conf = implode("\n", $lines);
2831         }
7fe908 2832
146783 2833         return trim($vhost_conf);
MC 2834     }
7fe908 2835
MC 2836     function client_delete($event_name, $data) {
146783 2837         global $app, $conf;
7fe908 2838
146783 2839         $app->uses("getconf");
MC 2840         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
7fe908 2841
146783 2842         $client_id = intval($data['old']['client_id']);
MC 2843         if($client_id > 0) {
7fe908 2844
146783 2845             $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id;
7fe908 2846             if(is_dir($client_dir) && !stristr($client_dir, '..')) {
146783 2847                 // remove symlinks from $client_dir
7fe908 2848                 $files = array_diff(scandir($client_dir), array('.', '..'));
146783 2849                 if(is_array($files) && !empty($files)){
MC 2850                     foreach($files as $file){
2851                         if(is_link($client_dir.'/'.$file)){
2852                             unlink($client_dir.'/'.$file);
7fe908 2853                             $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG);
146783 2854                         }
MC 2855                     }
2856                 }
7fe908 2857
146783 2858                 @rmdir($client_dir);
7fe908 2859                 $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG);
146783 2860             }
7fe908 2861
146783 2862             if($app->system->is_group('client'.$client_id)){
MC 2863                 $this->_exec('groupdel client'.$client_id);
7fe908 2864                 $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG);
146783 2865             }
MC 2866         }
7fe908 2867
146783 2868     }
MC 2869
2870     //* Wrapper for exec function for easier debugging
2871     private function _exec($command) {
2872         global $app;
7fe908 2873         $app->log('exec: '.$command, LOGLEVEL_DEBUG);
146783 2874         exec($command);
MC 2875     }
2876
7fe908 2877     private function _checkTcp ($host, $port) {
MC 2878
2879         $fp = @fsockopen($host, $port, $errno, $errstr, 2);
146783 2880
MC 2881         if ($fp) {
2882             fclose($fp);
2883             return true;
2884         } else {
2885             return false;
2886         }
2887     }
7fe908 2888
146783 2889     public function create_relative_link($f, $t) {
MC 2890         global $app;
2891         // $from already exists
2892         $from = realpath($f);
2893
2894         // realpath requires the traced file to exist - so, lets touch it first, then remove
2895         @$app->system->unlink($t); touch($t);
2896         $to = realpath($t);
2897         @$app->system->unlink($t);
2898
2899         // Remove from the left side matching path elements from $from and $to
2900         // and get path elements counts
2901         $a1 = explode('/', $from); $a2 = explode('/', $to);
2902         for ($c = 0; $a1[$c] == $a2[$c]; $c++) {
2903             unset($a1[$c]); unset($a2[$c]);
2904         }
2905         $cfrom = implode('/', $a1);
2906
2907         // Check if a path is fully a subpath of another - no way to create symlink in the case
2908         if (count($a1) == 0 || count($a2) == 0) return false;
2909
2910         // Add ($cnt_to-1) number of "../" elements to left side of $cfrom
2911         for ($c = 0; $c < (count($a2)-1); $c++) { $cfrom = '../'.$cfrom; }
2912
2913         return symlink($cfrom, $to);
2914     }
7fe908 2915
MC 2916     private function _rewrite_quote($string) {
2917         return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string);
2918     }
2919
146783 2920     private function url_is_local($hostname, $domain_id){
MC 2921         global $app;
2922
2923         // ORDER BY clause makes sure wildcard subdomains (*) are listed last in the result array so that we can find direct matches first
2924         $webs = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' ORDER BY subdomain ASC");
2925         if(is_array($webs) && !empty($webs)){
2926             foreach($webs as $web){
2927                 // web domain doesn't match hostname
7fe908 2928                 if(substr($hostname, -strlen($web['domain'])) != $web['domain']) continue;
146783 2929                 // own vhost and therefore server {} container of its own
511ba5 2930                 //if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') continue;
146783 2931                 // alias domains/subdomains using rewrites and therefore a server {} container of their own
MC 2932                 //if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') continue;
7fe908 2933
146783 2934                 if($web['subdomain'] == '*'){
MC 2935                     $pattern = '/\.?'.str_replace('.', '\.', $web['domain']).'$/i';
2936                 }
2937                 if($web['subdomain'] == 'none'){
2938                     if($web['domain'] == $hostname){
2939                         if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){
2940                             // own vhost and therefore server {} container of its own
511ba5 2941                             if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false;
146783 2942                             // alias domains/subdomains using rewrites and therefore a server {} container of their own
MC 2943                             if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false;
2944                             return true;
2945                         } else {
2946                             return false;
2947                         }
2948                     }
2949                     $pattern = '/^'.str_replace('.', '\.', $web['domain']).'$/i';
2950                 }
2951                 if($web['subdomain'] == 'www'){
2952                     if($web['domain'] == $hostname || $web['subdomain'].'.'.$web['domain'] == $hostname){
2953                         if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){
2954                             // own vhost and therefore server {} container of its own
511ba5 2955                             if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false;
146783 2956                             // alias domains/subdomains using rewrites and therefore a server {} container of their own
MC 2957                             if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false;
2958                             return true;
2959                         } else {
2960                             return false;
2961                         }
2962                     }
2963                     $pattern = '/^(www\.)?'.str_replace('.', '\.', $web['domain']).'$/i';
2964                 }
2965                 if(preg_match($pattern, $hostname)){
2966                     if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){
2967                         // own vhost and therefore server {} container of its own
511ba5 2968                         if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false;
146783 2969                         // alias domains/subdomains using rewrites and therefore a server {} container of their own
MC 2970                         if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false;
2971                         return true;
2972                     } else {
2973                         return false;
2974                     }
2975                 }
2976             }
2977         }
7fe908 2978
146783 2979         return false;
MC 2980     }
7fe908 2981
146783 2982     private function get_seo_redirects($web, $prefix = '', $force_subdomain = false){
MC 2983         // $force_subdomain = 'none|www'
2984         $seo_redirects = array();
7fe908 2985
146783 2986         if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*';
7fe908 2987
146783 2988         if(($web['subdomain'] == 'www' || $web['subdomain'] == '*') && $force_subdomain != 'www'){
MC 2989             if($web['seo_redirect'] == 'non_www_to_www'){
2990                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain'];
2991                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2992                 $seo_redirects[$prefix.'seo_redirect_operator'] = '=';
2993             }
2994             if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){
2995                 // ^(example\.com|(?!\bwww\b)\.example\.com)$
2996                 // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$
2997                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))$';
2998                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2999                 $seo_redirects[$prefix.'seo_redirect_operator'] = '~*';
3000             }
3001             if($web['seo_redirect'] == '*_to_www_domain_tld'){
3002                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain'];
3003                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
3004                 $seo_redirects[$prefix.'seo_redirect_operator'] = '!=';
3005             }
3006         }
3007         if($force_subdomain != 'none'){
3008             if($web['seo_redirect'] == 'www_to_non_www'){
3009                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain'];
3010                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
3011                 $seo_redirects[$prefix.'seo_redirect_operator'] = '=';
3012             }
3013             if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){
3014                 // ^(.+)\.example\.com$
3015                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^(.+)\.'.str_replace('.', '\.', $web['domain']).'$';
3016                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
3017                 $seo_redirects[$prefix.'seo_redirect_operator'] = '~*';
3018             }
3019             if($web['seo_redirect'] == '*_to_domain_tld'){
3020                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain'];
3021                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
3022                 $seo_redirects[$prefix.'seo_redirect_operator'] = '!=';
3023             }
3024         }
3025         return $seo_redirects;
3026     }
3027
3028 } // end class
3029
3030 ?>