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