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