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