tbrehm
2012-08-14 d87f76019fc231ec20d95126a7fee0487e7be5f0
- Added new web folder named private to web folder layout. The folder is intended to store data that shall not be visible in the web directory, it is owned by the user of the web.
- Changed ownership of web root directory to root user in all security modes to prevent symlink attacks.
- Apache log files are now owned by user root.
- Improved functions in system library.
2 files modified
104 ■■■■ changed files
server/lib/classes/system.inc.php 28 ●●●● patch | view | raw | blame | history
server/plugins-available/apache2_plugin.inc.php 76 ●●●●● patch | view | raw | blame | history
server/lib/classes/system.inc.php
@@ -617,7 +617,12 @@
        return false;
      }
      if(file_exists($file)) {
        return chown($file, $owner);
        if(@chown($file, $owner)) {
            return true;
        } else {
            $app->log("chown failed: $file : $owner",LOGLEVEL_DEBUG);
            return false;
        }
      }
    }
    
@@ -628,7 +633,12 @@
        return false;
      }
      if(file_exists($file)) {
        return chgrp($file, $group);
        if(@chgrp($file, $group)) {
            return true;
        } else {
            $app->log("chgrp failed: $file : $group",LOGLEVEL_DEBUG);
            return false;
        }
      }
    }
    
@@ -639,7 +649,12 @@
            $app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
            return false;
        }
        return chmod($file, $mode);
        if(@chmod($file, $mode)) {
            return true;
        } else {
            $app->log("chmod failed: $file : $mode",LOGLEVEL_DEBUG);
            return false;
        }
    }
    
    function file_put_contents($filename, $data, $allow_symlink = false) {
@@ -676,7 +691,12 @@
            $app->log("Action aborted, file is a symlink: $dirname",LOGLEVEL_WARN);
            return false;
        }
        return mkdir($dirname);
        if(@mkdir($dirname)) {
            return true;
        } else {
            $app->log("mkdir failed: $dirname",LOGLEVEL_DEBUG);
            return false;
        }
    }
    
    function unlink($file) {
server/plugins-available/apache2_plugin.inc.php
@@ -433,6 +433,8 @@
        //print_r($data);
        // Check if the directories are there and create them if necessary.
        $app->system->web_folder_protection($data['new']['document_root'],false);
        if(!is_dir($data['new']['document_root'].'/web')) $app->system->mkdirpath($data['new']['document_root'].'/web');
        if(!is_dir($data['new']['document_root'].'/web/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/web/error');
        //if(!is_dir($data['new']['document_root'].'/log')) exec('mkdir -p '.$data['new']['document_root'].'/log');
@@ -440,6 +442,16 @@
        if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
        if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp');
        if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav');
        //* Create the new private directory
        if(!is_dir($data['new']['document_root'].'/private')) {
            $app->system->mkdirpath($data['new']['document_root'].'/private');
            $app->system->chmod($data['new']['document_root'].'/private',0710);
            $app->system->chown($data['new']['document_root'].'/private',$username);
            $app->system->chgrp($data['new']['document_root'].'/private',$groupname);
        }
        $app->system->web_folder_protection($data['new']['document_root'],true);
        
        // Remove the symlink for the site, if site is renamed
        if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
@@ -459,21 +471,6 @@
            $app->log('Creating symlink: ln -s /var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/log',LOGLEVEL_DEBUG);
        }
        /*
        // Create the symlink for the logfiles
        // This does not work as vlogger cannot log trough symlinks.
        if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
            if(is_dir($data['old']['document_root'].'/log')) exec('rm -rf '.$data['old']['document_root'].'/log');
            if(is_link('/var/log/ispconfig/httpd/'.$data['old']['domain'])) $app->system->unlink('/var/log/ispconfig/httpd/'.$data['old']['domain']);
        }
        // Create the symlink for the logfiles
        if(!is_dir($data['new']['document_root'].'/log')) exec('mkdir -p '.$data['new']['document_root'].'/log');
        if(!is_link('/var/log/ispconfig/httpd/'.$data['new']['domain'])) {
            exec('ln -s '.$data['new']['document_root'].'/log /var/log/ispconfig/httpd/'.$data['new']['domain']);
            $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/log /var/log/ispconfig/httpd/'.$data['new']['domain'],LOGLEVEL_DEBUG);
        }
        */
        // Get the client ID
        $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['new']['sys_groupid']));
@@ -624,19 +621,16 @@
            
            $app->system->web_folder_protection($data['new']['document_root'],false);
            
            //* Check if we have the new private folder and create it if nescessary
            if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private');
            if($web_config['security_level'] == 20) {
                
                $app->system->chmod($data['new']['document_root'],0751);
                $app->system->chmod($data['new']['document_root'],0755);
                $app->system->chmod($data['new']['document_root'].'/web',0710);
                $app->system->chmod($data['new']['document_root'].'/webdav',0710);
                $app->system->chmod($data['new']['document_root'].'/private',0710);
                $app->system->chmod($data['new']['document_root'].'/ssl',0755);
                /*
                $this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']));
                $this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']).'/*');
                $this->_exec('chmod 710 '.escapeshellcmd($data['new']['document_root'].'/web'));
                $this->_exec('chmod 755 '.escapeshellcmd($data['new']['document_root'].'/ssl'));
                */
                // make tmp directory writable for Apache and the website users
                $app->system->chmod($data['new']['document_root'].'/tmp',0777);
@@ -669,16 +663,8 @@
                $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
                
                //* Chown all default directories
                /*
                $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']));
                $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/cgi-bin'));
                $this->_exec('chown root:'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/log'));
                $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root'].'/ssl'));
                $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/tmp'));
                $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/web'));
                */
                $app->system->chown($data['new']['document_root'],$username);
                $app->system->chgrp($data['new']['document_root'],$groupname);
                $app->system->chown($data['new']['document_root'],'root');
                $app->system->chgrp($data['new']['document_root'],'root');
                $app->system->chown($data['new']['document_root'].'/cgi-bin',$username);
                $app->system->chgrp($data['new']['document_root'].'/cgi-bin',$groupname);
                if(realpath($data['new']['document_root'].'/log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
@@ -697,22 +683,8 @@
                $app->system->chgrp($data['new']['document_root'].'/web/stats',$groupname);
                $app->system->chown($data['new']['document_root'].'/webdav',$username);
                $app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
                /*
                * Workaround for jailkit: If jailkit is enabled for the site, the
                * website root has to be owned by the root user and we have to chmod it to 755 then
                */
                //* Check if there is a jailkit user or cronjob for this site
                $tmp = $app->db->queryOneRecord('SELECT count(shell_user_id) as number FROM shell_user WHERE parent_domain_id = '.$data['new']['domain_id']." AND chroot = 'jailkit'");
                $tmp2 = $app->db->queryOneRecord('SELECT count(id) as number FROM cron WHERE parent_domain_id = '.$data['new']['domain_id']." AND `type` = 'chrooted'");
                if($tmp['number'] > 0 || $tmp2['number'] > 0) {
                    $app->system->chmod($data['new']['document_root'],0755);
                    $app->system->chown($data['new']['document_root'],'root');
                    $app->system->chgrp($data['new']['document_root'],'root');
                }
                unset($tmp);
                $app->system->chown($data['new']['document_root'].'/private',$username);
                $app->system->chgrp($data['new']['document_root'].'/private',$groupname);
                // If the security Level is set to medium
            } else {
@@ -755,10 +727,10 @@
        //* Protect web folders
        $app->system->web_folder_protection($data['new']['document_root'],true);
        // Change the ownership of the error log to the owner of the website
        // Change the ownership of the error log to the root user
        if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log'));
        $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log',$username);
        $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log',$groupname);
        $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log','root');
        $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log','root');
        //* Write the custom php.ini file, if custom_php_ini fieled is not empty