| | |
| | | * @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'; |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | | * |
| | | */ |
| | |
| | | * 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; |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | /* |
| | | function usermod($user, $groups){ |
| | | global $app; |
| | | if($this->is_user($user)){ |
| | |
| | | return false; |
| | | } |
| | | } |
| | | */ |
| | | |
| | | /**boot autostart etc |
| | | * |
| | |
| | | function make_trashscan(){ |
| | | global $app; |
| | | //trashscan erstellen |
| | | // Template Öffnen |
| | | // Template Öffnen |
| | | $app->tpl->clear_all(); |
| | | $app->tpl->define( array(table => 'trashscan.master')); |
| | | |
| | |
| | | } |
| | | |
| | | 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; |
| | |
| | | |
| | | 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) { |
| | |
| | | } 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; |
| | | } |
| | |
| | | $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); |
| | |
| | | $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; |
| | | } |
| | | |
| | | } |
| | | ?> |