tbrehm
2013-04-16 a0fd5ab7b5412985324e970573ca22a27b3a94d3
server/lib/classes/system.inc.php
@@ -41,9 +41,9 @@
    * @return system
    */
   public function system(){
      global $go_info;
        $this->server_id = $go_info['isp']['server_id'];
        $this->server_conf = $go_info['isp']['server_conf'];
      //global $go_info;
        //$this->server_id = $go_info['isp']['server_id'];
        //$this->server_conf = $go_info['isp']['server_conf'];
        $this->server_conf['passwd_datei'] = '/etc/passwd';
        $this->server_conf['shadow_datei'] = '/etc/shadow';
        $this->server_conf['group_datei'] = '/etc/group';
@@ -575,6 +575,58 @@
   }
   
   /**
    * Get the group id from an group
    *
    */
   function getgid($group){
      global $app;
        if($this->is_group($group)){
          $group_datei = $this->server_conf['group_datei'];
         $groups = $app->file->no_comments($group_datei);
         $lines = explode("\n", $groups);
         if(is_array($lines)){
          foreach($lines as $line){
               if(trim($line) != ""){
                  list($f1, $f2, $f3, $f4) = explode(':', $line);
                  if($f1 == $group) return $f3;
               }
            }
         }
        } else {
          return false;
        }
   }
   /**
   * Return info about a group by name
   *
   */
   function posix_getgrnam($group) {
      if(!function_exists('posix_getgrnam')){
         $group_datei = $this->server_conf['group_datei'];
         $cmd = 'grep -m 1 "^'.$group.':" '.$group_datei;
         exec($cmd, $output, $return_var);
         if($return_var != 0 || !$output[0]) return false;
         list($f1, $f2, $f3, $f4) = explode(':', $output[0]);
         $f2 = trim($f2);
         $f3 = trim($f3);
         $f4 = trim($f4);
         if($f4 != ''){
            $members = explode(',', $f4);
         } else {
            $members = array();
         }
         $group_details = array(   'name' => $group,
                           'passwd' => $f2,
                           'members' => $members,
                           'gid' => $f3);
         return $group_details;
      } else {
         return posix_getgrnam($group);
      }
    }
   /**
    * Get all information from a user
    *
    */
@@ -610,18 +662,135 @@
    * Edit the owner of a file
    *
    */
   function chown($file, $owner, $group = ''){
     $owner_change = @chown($file, $owner);
     if($group != ''){
       $group_change = @chgrp($file, $group);
     } else {
       $group_change = 1;
   function chown($file, $owner, $allow_symlink = false){
     global $app;
     if($allow_symlink == false && $this->checkpath($file) == false) {
      $app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
      return false;
     }
     if($owner_change && $group_change){
       return true;
     } else {
       return false;
     if(file_exists($file)) {
      if(@chown($file, $owner)) {
         return true;
      } else {
         $app->log("chown failed: $file : $owner",LOGLEVEL_DEBUG);
         return false;
      }
     }
   }
   function chgrp($file, $group = '', $allow_symlink = false){
     global $app;
     if($allow_symlink == false && $this->checkpath($file) == false) {
      $app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
      return false;
     }
     if(file_exists($file)) {
      if(@chgrp($file, $group)) {
         return true;
      } else {
         $app->log("chgrp failed: $file : $group",LOGLEVEL_DEBUG);
         return false;
      }
     }
   }
   //* Change the mode of a file
   function chmod($file, $mode, $allow_symlink = false) {
      global $app;
      if($allow_symlink == false && $this->checkpath($file) == false) {
         $app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
         return false;
      }
      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) {
      global $app;
      if($allow_symlink == false && $this->checkpath($filename) == false) {
         $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
         return false;
      }
      if(file_exists($filename)) unlink($filename);
      return file_put_contents($filename, $data);
   }
   function file_get_contents($filename, $allow_symlink = false) {
      global $app;
      if($allow_symlink == false && $this->checkpath($filename) == false) {
         $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
         return false;
      }
      return file_get_contents($filename, $data);
   }
   function rename($filename, $new_filename, $allow_symlink = false) {
      global $app;
      if($allow_symlink == false && $this->checkpath($filename) == false) {
         $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
         return false;
      }
      return rename($filename, $new_filename);
   }
   function mkdir($dirname, $allow_symlink = false) {
      global $app;
      if($allow_symlink == false && $this->checkpath($dirname) == false) {
         $app->log("Action aborted, file is a symlink: $dirname",LOGLEVEL_WARN);
         return false;
      }
      if(@mkdir($dirname)) {
         return true;
      } else {
         $app->log("mkdir failed: $dirname",LOGLEVEL_DEBUG);
         return false;
      }
   }
   function unlink($filename) {
      if(file_exists($filename) || is_link($filename)) {
         return unlink($filename);
      }
   }
   function copy($file1,$file2) {
      return copy($file1,$file2);
   }
   function touch($file, $allow_symlink = false){
     global $app;
     if($allow_symlink == false && @file_exists($file) && $this->checkpath($file) == false) {
      $this->unlink($file);
     }
     if(@touch($file)) {
         return true;
     } else {
         $app->log("touch failed: $file",LOGLEVEL_DEBUG);
         return false;
     }
   }
   function checkpath($path) {
      $path = trim($path);
      //* We allow only absolute paths
      if(substr($path,0,1) != '/') return false;
      //* We allow only some characters in the path
      if(!preg_match('/[a-zA-Z0-9_\.\-]{1,}/',$path)) return false;
      //* Check path for symlinks
      $path_parts = explode('/',$path);
      $testpath = '';
      foreach($path_parts as $p) {
         $testpath .= '/'.$p;
         if(is_link($testpath)) return false;
      }
      return true;
   }
   
   /**
@@ -653,6 +822,7 @@
        }
   }
   
   /*
   function usermod($user, $groups){
      global $app;
        if($this->is_user($user)){
@@ -692,6 +862,7 @@
          return false;
        }
   }
   */
   
   /**boot autostart etc
    *
@@ -1046,7 +1217,7 @@
   function make_trashscan(){
      global $app;
        //trashscan erstellen
        // Template Öffnen
        // Template Öffnen
        $app->tpl->clear_all();
        $app->tpl->define( array(table    => 'trashscan.master'));
   
@@ -1132,6 +1303,11 @@
   }
   
   function replaceLine($filename,$search_pattern,$new_line,$strict = 0,$append = 1) {
      global $app;
      if($this->checkpath($filename) == false) {
         $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
         return false;
      }
      $lines = @file($filename);
      $out = '';
      $found = 0;
@@ -1157,14 +1333,21 @@
      
      if($found == 0) {
         //* add \n if the last line does not end with \n or \r
         if(substr($out,-1) != "\n" && substr($out,-1) != "\r") $out .= "\n";
         if(substr($out,-1) != "\n" && substr($out,-1) != "\r" && filesize($filename) > 0) $out .= "\n";
         //* add the new line at the end of the file
         if($append == 1) $out .= $new_line."\n";
         if($append == 1) {
            $out .= $new_line."\n";
         }
      }
      file_put_contents($filename,$out);
   }
   
   function removeLine($filename,$search_pattern,$strict = 0) {
   global $app;
   if($this->checkpath($filename) == false) {
      $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
      return false;
   }
   if($lines = @file($filename)) {
      $out = '';
      foreach($lines as $line) {
@@ -1191,13 +1374,15 @@
      } else {
         $dir = escapeshellcmd($maildir_path);
      }
      if(!is_dir($dir)) mkdir($dir, 0700, true);
      if($user != '' && $user != 'root' && $this->is_user($user)) {
         $user = escapeshellcmd($user);
         // I assume that the name of the (vmail group) is the same as the name of the mail user in ISPConfig 3
         $group = $user;
         chown($dir,$user);
         chgrp($dir,$group);
         if(is_dir($dir)) $this->chown($dir,$user);
         if(is_dir($dir)) $this->chgrp($dir,$group);
         $chown_mdsub = true;
      }
@@ -1205,7 +1390,7 @@
      $maildirsubs = array('cur','new','tmp');
      foreach ($maildirsubs as $mdsub) {
         mkdir($dir.'/'.$mdsub, 0700, true);
         if(!is_dir($dir.'/'.$mdsub)) mkdir($dir.'/'.$mdsub, 0700, true);
         if ($chown_mdsub) {
            chown($dir.'/'.$mdsub, $user);
            chgrp($dir.'/'.$mdsub, $group);
@@ -1249,6 +1434,168 @@
      $app->log('Created Maildir '.$maildir_path.' with subfolder: '.$subfolder,LOGLEVEL_DEBUG);
      
   }
   //* Function to create directory paths and chown them to a user and group
   function mkdirpath($path, $mode = 0755, $user = '', $group = '') {
      $path_parts = explode('/',$path);
      $new_path = '';
      if(is_array($path_parts)) {
         foreach($path_parts as $part) {
            $new_path .= '/'.$part;
            if(!@is_dir($new_path)) {
               $this->mkdir($new_path);
               $this->chmod($new_path,$mode);
               if($user != '') $this->chown($new_path,$user);
               if($group != '') $this->chgrp($new_path,$group);
            }
         }
      }
   }
   //* Check if a application is installed
   function is_installed($appname) {
      exec('which '.escapeshellcmd($appname).' 2> /dev/null',$out,$returncode);
      if(isset($out[0]) && stristr($out[0],$appname) && $returncode == 0) {
         return true;
      } else {
         return false;
      }
   }
   function web_folder_protection($document_root,$protect) {
      global $app,$conf;
      if($this->checkpath($document_root) == false) {
         $app->log("Action aborted, target is a symlink: $document_root",LOGLEVEL_DEBUG);
         return false;
      }
      //* 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));
      }
   }
   function usermod($username, $uid = 0, $gid = 0, $home = '', $shell = '', $password = '', $login = '') {
      global $app;
      if($login == '') $login = $username;
      //* Change values in /etc/passwd
      $passwd_file_array = file('/etc/passwd');
      if(is_array($passwd_file_array)) {
         foreach($passwd_file_array as $line) {
            $line = trim($line);
            $parts = explode(':',$line);
            if($parts[0] == $username) {
               if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
               if(!empty($uid)) $parts[2] = trim($uid);
               if(!empty($gid)) $parts[3] = trim($gid);
               if(trim($home) != '') $parts[5] = trim($home);
               if(trim($shell) != '') $parts[6] = trim($shell);
               $new_line = implode(':',$parts);
               copy('/etc/passwd','/etc/passwd~');
               chmod('/etc/passwd~',0600);
               $app->uses('system');
               $app->system->replaceLine('/etc/passwd',$line,$new_line,1,0);
            }
         }
         unset($passwd_file_array);
      }
      //* If username != login, change username in group and gshadow file
      if($username  != $login) {
         $group_file_array = file('/etc/group');
         if(is_array($group_file_array)) {
            foreach($group_file_array as $line) {
               $line = trim($line);
               $parts = explode(':',$line);
               if(strstr($parts[3],$username)) {
                  $uparts = explode(',',$parts[3]);
                  if(is_array($uparts)) {
                     foreach($uparts as $key => $val) {
                        if($val == $username) $uparts[$key] = $login;
                     }
                  }
                  $parts[3] = implode(',',$uparts);
                  $new_line = implode(':',$parts);
                  copy('/etc/group','/etc/group~');
                  chmod('/etc/group~',0600);
                  $app->system->replaceLine('/etc/group',$line,$new_line,1,0);
               }
            }
         }
         unset($group_file_array);
         $gshadow_file_array = file('/etc/gshadow');
         if(is_array($gshadow_file_array)) {
            foreach($gshadow_file_array as $line) {
               $line = trim($line);
               $parts = explode(':',$line);
               if(strstr($parts[3],$username)) {
                  $uparts = explode(',',$parts[3]);
                  if(is_array($uparts)) {
                     foreach($uparts as $key => $val) {
                        if($val == $username) $uparts[$key] = $login;
                     }
                  }
                  $parts[3] = implode(',',$uparts);
                  $new_line = implode(':',$parts);
                  copy('/etc/gshadow','/etc/gshadow~');
                  chmod('/etc/gshadow~',0600);
                  $app->system->replaceLine('/etc/gshadow',$line,$new_line,1,0);
               }
            }
         }
         unset($group_file_array);
      }
      //* When password or login name has been changed
      if($password != '' || $username  != $login) {
         $shadow_file_array = file('/etc/shadow');
         if(is_array($shadow_file_array)) {
            foreach($shadow_file_array as $line) {
               $line = trim($line);
               $parts = explode(':',$line);
               if($parts[0] == $username) {
                  if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
                  if(trim($password) != '') $parts[1] = trim($password);
                  $new_line = implode(':',$parts);
                  copy('/etc/shadow','/etc/shadow~');
                  chmod('/etc/shadow~',0600);
                  $app->system->replaceLine('/etc/shadow',$line,$new_line,1,0);
               }
            }
         }
         unset($shadow_file_array);
      }
   }
   function intval($string, $force_numeric = false) {
        if(intval($string) == 2147483647) {
            if($force_numeric == true) return floatval($string);
            elseif(preg_match('/^([-]?)[0]*([1-9][0-9]*)([^0-9].*)*$/', $string, $match)) return $match[1].$match[2];
            else return 0;
        } else {
            return intval($string);
        }
    }
   function is_mounted($mountpoint){
      //$cmd = 'df 2>/dev/null | grep " '.$mountpoint.'$"';
      $cmd = 'mount 2>/dev/null | grep " on '.$mountpoint.' type "';
      exec($cmd, $output, $return_var);
      return $return_var == 0 ? true : false;
   }
}
?>