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