tbrehm
2012-06-08 4b9329a0f204c190f9cae6c072c9827d05d269e6
Implemented: FS#2112 - Set u / i attributes on system web folders
This option can be enabled under System > Server config and is named "Web folder protection".
9 files modified
75 ■■■■■ changed files
install/tpl/server.ini.master 1 ●●●● patch | view | raw | blame | history
interface/web/admin/form/server_config.tform.php 6 ●●●●● patch | view | raw | blame | history
interface/web/admin/lib/lang/en_server_config.lng 1 ●●●● patch | view | raw | blame | history
interface/web/admin/templates/server_config_web_edit.htm 6 ●●●●● patch | view | raw | blame | history
server/lib/classes/system.inc.php 16 ●●●●● patch | view | raw | blame | history
server/plugins-available/apache2_plugin.inc.php 17 ●●●● patch | view | raw | blame | history
server/plugins-available/cron_jailkit_plugin.inc.php 6 ●●●●● patch | view | raw | blame | history
server/plugins-available/shelluser_base_plugin.inc.php 7 ●●●●● patch | view | raw | blame | history
server/plugins-available/shelluser_jailkit_plugin.inc.php 15 ●●●●● patch | view | raw | blame | history
install/tpl/server.ini.master
@@ -76,6 +76,7 @@
add_web_users_to_sshusers_group=y
connect_userid_to_webid=n
connect_userid_to_webid_start=10000
web_folder_protection=n
[dns]
bind_user=root
interface/web/admin/form/server_config.tform.php
@@ -462,6 +462,12 @@
            'default' => 'y',
            'value' => array(0 => 'n', 1 => 'y')
        ),
        'web_folder_protection' => array(
            'datatype' => 'VARCHAR',
            'formtype' => 'CHECKBOX',
            'default' => 'y',
            'value' => array(0 => 'n', 1 => 'y')
        ),
        'add_web_users_to_sshusers_group' => array(
            'datatype' => 'VARCHAR',
            'formtype' => 'CHECKBOX',
interface/web/admin/lib/lang/en_server_config.lng
@@ -165,4 +165,5 @@
$wb["firewall_txt"] = 'Firewall';
$wb["mailbox_quota_stats_txt"] = 'Mailbox quota statistics';
$wb["enable_ip_wildcard_txt"] = 'Enable IP wildcard (*)';
$wb["web_folder_protection_txt"] = 'Web folder protection';
?>
interface/web/admin/templates/server_config_web_edit.htm
@@ -117,6 +117,12 @@
                    </div>
            </div>
      <div class="ctrlHolder">
                <p class="label">{tmpl_var name='web_folder_protection_txt'}</p>
                    <div class="multiField">
                        {tmpl_var name='web_folder_protection'}
                    </div>
            </div>
      <div class="ctrlHolder">
                <p class="label">{tmpl_var name='add_web_users_to_sshusers_group_txt'}</p>
                    <div class="multiField">
                        {tmpl_var name='add_web_users_to_sshusers_group'}
server/lib/classes/system.inc.php
@@ -1281,6 +1281,22 @@
            return false;
        }
    }
    function web_folder_protection($document_root,$protect) {
        global $app,$conf;
        //* load the server configuration options
        $app->uses('getconf');
        $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
        if($protect == true && $web_config['web_folder_protection'] == 'y') {
            //* Add protection
            if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root,'..')) exec('chattr +i '.escapeshellcmd($document_root));
        } else {
            //* Remove protection
            if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root,'..')) exec('chattr -i '.escapeshellcmd($document_root));
        }
    }
}
?>
server/plugins-available/apache2_plugin.inc.php
@@ -366,6 +366,9 @@
                    }
                }
            }
            //* Remove protection of old folders
            $app->system->web_folder_protection($data['old']['document_root'],false);
            //* Move the site data
            $tmp_docroot = explode('/',$data['new']['document_root']);
@@ -414,7 +417,7 @@
        if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
        if(!is_dir($data['new']['document_root'].'/cgi-bin')) exec('mkdir -p '.$data['new']['document_root'].'/cgi-bin');
        if(!is_dir($data['new']['document_root'].'/tmp')) exec('mkdir -p '.$data['new']['document_root'].'/tmp');
        // Remove the symlink for the site, if site is renamed
        if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
            if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
@@ -593,10 +596,11 @@
            }
        }
        //* If the security level is set to high
        if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
            $app->system->web_folder_protection($data['new']['document_root'],false);
            if($web_config['security_level'] == 20) {
                $this->_exec('chmod 751 '.escapeshellcmd($data['new']['document_root']));
@@ -673,6 +677,9 @@
                $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root'].'/web'));
            }
        }
        //* 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
        if(!@is_file($data['new']['document_root'].'/log/error.log')) exec('touch '.escapeshellcmd($data['new']['document_root']).'/log/error.log');
@@ -1217,7 +1224,9 @@
        if(!is_file($data['new']['document_root'].'/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
            if(trim($data['new']['stats_password']) != '') {
                $htp_file = 'admin:'.trim($data['new']['stats_password']);
                $app->system->web_folder_protection($data['new']['document_root'],false);
                file_put_contents($data['new']['document_root'].'/.htpasswd_stats',$htp_file);
                $app->system->web_folder_protection($data['new']['document_root'],true);
                chmod($data['new']['document_root'].'/.htpasswd_stats',0755);
                unset($htp_file);
            }
@@ -1280,6 +1289,8 @@
        // load the server configuration options
        $app->uses('getconf');
        $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
        $app->system->web_folder_protection($data['new']['document_root'],false);
        //* Check if this is a chrooted setup
        if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
server/plugins-available/cron_jailkit_plugin.inc.php
@@ -116,6 +116,8 @@
                $this->app = $app;
                $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
                
                $app->system->web_folder_protection($parent_domain['document_root'],false);
                $this->_update_website_security_level();
            
                $this->_setup_jailkit_chroot();
@@ -126,6 +128,8 @@
                exec($command);
                
                $this->_update_website_security_level();
                $app->system->web_folder_protection($parent_domain['document_root'],true);
            }
        
            $app->log("Jailkit Plugin (Cron) -> insert username:".$parent_domain['system_user'],LOGLEVEL_DEBUG);
@@ -182,12 +186,14 @@
                $this->app = $app;
                $this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
                
                $app->system->web_folder_protection($parent_domain['document_root'],false);
                $this->_update_website_security_level();
            
                $this->_setup_jailkit_chroot();
                $this->_add_jailkit_user();
                
                $this->_update_website_security_level();
                $app->system->web_folder_protection($parent_domain['document_root'],true);
            }
        
            $app->log("Jailkit Plugin (Cron) -> update username:".$parent_domain['system_user'],LOGLEVEL_DEBUG);
server/plugins-available/shelluser_base_plugin.inc.php
@@ -80,6 +80,10 @@
        }
        
        if($app->system->is_user($data['new']['puser'])) {
            //* Remove webfolder protection
            $app->system->web_folder_protection($web['document_root'],false);
            // Get the UID of the parent user
            $uid = intval($app->system->getuid($data['new']['puser']));
            if($uid > $this->min_uid) {
@@ -114,6 +118,9 @@
                    exec($command);
                    $app->log("Disabling shelluser temporarily: ".$command,LOGLEVEL_DEBUG);
                }
                //* Add webfolder protection again
                $app->system->web_folder_protection($web['document_root'],true);
            
            } else {
                $app->log("UID = $uid for shelluser:".$data['new']['username']." not allowed.",LOGLEVEL_ERROR);
server/plugins-available/shelluser_jailkit_plugin.inc.php
@@ -71,6 +71,7 @@
        global $app, $conf;
        
        $app->uses('system');
        $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$this->data['new']['parent_domain_id']);
        
        if($app->system->is_user($data['new']['username'])) {
        
@@ -79,6 +80,8 @@
             */
            if ($data['new']['chroot'] == "jailkit")
            {
                $app->system->web_folder_protection($web['document_root'],false);
                // load the server configuration options
                $app->uses("getconf");
                $this->data = $data;
@@ -98,6 +101,7 @@
                exec($command);
                
                $this->_update_website_security_level();
                $app->system->web_folder_protection($web['document_root'],true);
            }
        
            $app->log("Jailkit Plugin -> insert username:".$data['new']['username'],LOGLEVEL_DEBUG);
@@ -113,6 +117,7 @@
        global $app, $conf;
        
        $app->uses('system');
        $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$this->data['new']['parent_domain_id']);
        
        if($app->system->is_user($data['new']['username'])) {
        
@@ -121,6 +126,8 @@
             */
            if ($data['new']['chroot'] == "jailkit")
            {
                $app->system->web_folder_protection($web['document_root'],false);
                // load the server configuration options
                $app->uses("getconf");
                $this->data = $data;
@@ -136,6 +143,8 @@
                $this->_setup_ssh_rsa();
                
                $this->_update_website_security_level();
                $app->system->web_folder_protection($web['document_root'],true);
            }
        
            $app->log("Jailkit Plugin -> update username:".$data['new']['username'],LOGLEVEL_DEBUG);
@@ -155,6 +164,8 @@
        
        $app->uses('system');
        
        $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$this->data['old']['parent_domain_id']);
        if ($data['old']['chroot'] == "jailkit")
        {
            $app->uses("getconf");
@@ -165,6 +176,8 @@
            //commented out proved to be dangerous on config errors
            //exec('rm -rf '.$data['old']['dir'].$jailkit_chroot_userhome);
            
            $app->system->web_folder_protection($web['document_root'],false);
            if(@is_dir($data['old']['dir'].$jailkit_chroot_userhome)) {
                $command = 'userdel -f';
                $command .= ' '.escapeshellcmd($data['old']['username']);
@@ -172,6 +185,8 @@
                $app->log("Jailkit Plugin -> delete chroot home:".$data['old']['dir'].$jailkit_chroot_userhome,LOGLEVEL_DEBUG);
            }
            
            $app->system->web_folder_protection($web['document_root'],true);
        }
        
        $app->log("Jailkit Plugin -> delete username:".$data['old']['username'],LOGLEVEL_DEBUG);