diff --git a/bureau/class/m_action.php b/bureau/class/m_action.php index 8f9ef846..ed35ae70 100644 --- a/bureau/class/m_action.php +++ b/bureau/class/m_action.php @@ -34,7 +34,7 @@ class m_action { */ function do_action(){ global $err, $L_INOTIFY_DO_ACTION; - $err->log("admin","do_action"); + $err->log("action","do_action"); touch($L_INOTIFY_DO_ACTION); } @@ -110,7 +110,6 @@ class m_action { case 'fix_dir': $query="insert into actions values ('','FIXDIR','$serialized',now(),'','','$user','');"; break; - case 'delete': $query="insert into actions values ('','DELETE','$serialized',now(),'','','$user','');"; break; default: diff --git a/bureau/class/m_bro.php b/bureau/class/m_bro.php index 34e70d11..3a2bc7e9 100644 --- a/bureau/class/m_bro.php +++ b/bureau/class/m_bro.php @@ -540,7 +540,7 @@ class m_bro { * @returns the path where the file resides or false if upload failed */ function UploadFile($R) { - global $_FILES,$err,$cuid; + global $_FILES,$err,$cuid,$action; $absolute=$this->convertabsolute($R,0); if (!$absolute) { $err->raise("bro",_("File or folder name is incorrect")); @@ -552,7 +552,7 @@ class m_bro { @touch($absolute."/".$_FILES['userfile']['name']); } if (@move_uploaded_file($_FILES['userfile']['tmp_name'], $absolute."/".$_FILES['userfile']['name'])) { - exec("sudo /usr/lib/alternc/fixperms.sh -u ".$cuid." -f '".$absolute."/".$_FILES['userfile']['name']."'"); + $action->fix_dir($absolute."/".$_FILES['userfile']['name']); return $absolute."/".$_FILES['userfile']['name']; } else { $err->raise("bro",_("Cannot create the requested file. Please check the permissions")); @@ -576,7 +576,7 @@ class m_bro { * @return boolean != 0 on error */ function ExtractFile($file, $dest=null) { - global $err,$cuid,$mem; + global $err,$cuid,$mem,$action; $file = $this->convertabsolute($file,0); if (is_null($dest)) { $dest = dirname($file); @@ -588,8 +588,9 @@ class m_bro { return 1; } $file = escapeshellarg($file); + $dest_to_fix = $dest; $dest = escapeshellarg($dest); - $dest_to_fix=str_replace(getuserpath(),'',$dest); + #$dest_to_fix=str_replace(getuserpath(),'',$dest); // TODO new version of tar supports `tar xf ...` so there is no // need to specify the compression format @@ -609,7 +610,7 @@ class m_bro { $err->raise("bro",_("I cannot find a way to extract the file %s, it is an unsupported compressed format"), $file); } // fix the perms of the extracted archive TODO: does it work??? - exec("sudo /usr/lib/alternc/fixperms.sh -u ".$cuid." -d ".$dest_to_fix); + $action->fix_dir($dest_to_fix); return $ret; } diff --git a/debian/alternc.cron.d b/debian/alternc.cron.d index 3731e344..e6ce2f96 100644 --- a/debian/alternc.cron.d +++ b/debian/alternc.cron.d @@ -31,5 +31,8 @@ # Every 30 minutes, do cron_users actions 00,30 * * * * alterncpanel /usr/lib/alternc/cron_users.sh +# Every 20 minutes, do actions +00,20 * * * * root /usr/lib/alternc/do_actions.php + # Every hour, stop expired VMs 10 * * * * alterncpanel /usr/lib/alternc/lxc_stopexpired.php diff --git a/src/do_actions.php b/src/do_actions.php index 2a03cdba..a7ff9651 100644 --- a/src/do_actions.php +++ b/src/do_actions.php @@ -35,7 +35,8 @@ */ // Put this var to 1 if you want to enable debug prints -$debug=0; +$debug=1; +$error_raise=''; // Debug function that print infos function d($mess){ @@ -44,6 +45,12 @@ function d($mess){ echo "$mess\n"; } +// Function to mail the panel's administrator if something failed +function mail_it(){ + global $error_raise; + mail("alterncpanel",'Cron do_actions.php failed!',$error_raise); +} + require_once("/usr/share/alternc/panel/class/config_nochk.php"); $LOCK_FILE='/var/run/alternc/do_actions_cron.lock'; @@ -63,7 +70,7 @@ if (file_exists($LOCK_FILE) !== false){ exit(0); }else{ // Previous cron failed! - echo "No process with PID $PID found! Previous cron failed...\n"; + $error_raise.="No process with PID $PID found! Previous cron failed...\n"; d("Removing lock file and trying to process the failed action..."); // Delete the lock and continue to the next action unlink($LOCK_FILE); @@ -71,7 +78,9 @@ if (file_exists($LOCK_FILE) !== false){ // Lock with the current script's PID d("Lock the script..."); if (file_put_contents($LOCK_FILE,$MY_PID) === false){ - die("Cannot open/write $LOCK_FILE"); + $error_raise.="Cannot open/write $LOCK_FILE\n"; + mail_it(); + exit(1); } // Get the action(s) that was processing when previous script failed @@ -86,9 +95,9 @@ if (file_exists($LOCK_FILE) !== false){ $action->reset_job($c["id"]); }else{ // We can't resume the others types, notify the fail and finish this action - echo "Can't resume the job n°".$c["id"]." action '".$c["type"]."', finishing it with a fail status.\n"; + $error_raise.="Can't resume the job n°".$c["id"]." action '".$c["type"]."', finishing it with a fail status.\n"; if(!$action->finish($c["id"],"Fail: Previous script crashed while processing this action, cannot resume it.")){ - echo "Cannot finish the action! Error while inserting the error value in the DB for action n°".$c["id"]." : action '".$c["type"]."'\n"; + $error_raise.="Cannot finish the action! Error while inserting the error value in the DB for action n°".$c["id"]." : action '".$c["type"]."'\n"; break; // Else we go into an infinite loop... AAAAHHHHHH } } @@ -98,7 +107,9 @@ if (file_exists($LOCK_FILE) !== false){ // Lock with the current script's PID d("Lock the script..."); if (file_put_contents($LOCK_FILE,$MY_PID) === false){ - die("Cannot open/write $LOCK_FILE"); + $error_raise.="Cannot open/write $LOCK_FILE\n"; + mail_it(); + exit(1); } } @@ -106,72 +117,71 @@ if (file_exists($LOCK_FILE) !== false){ while ($rr=$action->get_action()){ $r=$rr[0]; $return="OK"; + // Do we have to do this action with a specific user? + if($r["user"] != "root") + $SU="su ".$r["user"]." 2>&1 ;"; + else + $SU=""; unset($output); // We lock the action d("-----------\nBeginning action n°".$r["id"]); $action->begin($r["id"]); // We process it $params=unserialize($r["parameters"]); - // Remove all previous error message... - @trigger_error(""); // We exec with the specified user d("Executing action '".$r["type"]."' with user '".$r["user"]."'"); - // For now, this script only work for user 'root' - if($r["user"] != "root"){ - // TODO - } switch ($r["type"]){ case "CREATE_FILE" : if(!file_exists($params["file"])) - @file_put_contents($params["file"],$params["content"]); + @exec("$SU touch ".$params["file"]." 2>&1 ; echo '".$params["content"]."' > '".$params["file"]."' 2>&1", $output); else $output=array("Fail: file already exists"); break; case "CREATE_DIR" : // Create the directory and make parent directories as needed - @mkdir($params["dir"],0777,true); + @exec("$SU mkdir -p ".$params["dir"]." 2>&1",$output); break; case "DELETE" : // Delete file/directory and its contents recursively - @exec("rm -rf ".$params["dir"]." 2>&1", $output); + @exec("$SU rm -rf ".$params["dir"]." 2>&1", $output); break; case "MOVE" : // If destination dir does not exists, create it if(!is_dir($params["dst"])) - @mkdir($params["dst"],0777,true); - @exec("mv -f ".$params["src"]." ".$params["dst"]." 2>&1", $output); - // If MOVE failed, we have to notify the cron - if(isset($output[0])) - echo "Action n°".$r["id"]." 'MOVE' failed!\nuser: ".$r["user"]."\nsource: ".$params["src"]."\ndestination: ".$params["dst"]."\n"; + @exec("$SU mkdir -p ".$params["dst"]." 2>&1",$output); + if(!isset($output[0])) + @exec("$SU mv -f ".$params["src"]." ".$params["dst"]." 2>&1", $output); break; case "FIXDIR" : - @exec("$FIXPERM -f ".$params["dir"]." 2>&1", $trash, $code); + @exec("$SU $FIXPERM -d ".$params["dir"]." 2>&1", $trash, $code); if($code!=0) - $output[0]=$code; + $output[0]="Fixperms.sh failed, returned error code : $code"; break; default : $output=array("Fail: Sorry dude, i do not know this type of action"); break; } - // Get the last error if exists. - if(isset($output[0])) + // Get the error (if exists). + if(isset($output[0])){ $return=$output[0]; - else - if($error=error_get_last()) - if($error["message"]!="") - $return=$error["message"]; + $error_raise.="Action n°".$r["id"]." '".$r["type"]."' failed! With user: ".$r["user"]."\nHere is the complete output:\n".print_r($output); + } // We finished the action, notify the DB. d("Finishing... return value is : $return\n"); if(!$action->finish($r["id"],addslashes($return))){ - echo "Cannot finish the action! Error while inserting the error value in the DB for action n°".$c["id"]." : action '".$c["type"]."'\nReturn value: ".addslashes($return)."\n"; + $error_raise.="Cannot finish the action! Error while inserting the error value in the DB for action n°".$c["id"]." : action '".$c["type"]."'\nReturn value: ".addslashes($return)."\n"; break; // Else we go into an infinite loop... AAAAHHHHHH } } +// If something have failed, notify it to the admin +if($error_raise === '') + mail_it(); + // Unlock the script d("Unlock the script..."); unlink($LOCK_FILE); - +mail("alterncpanel@$L_FQDN","test do_actions.php","ceci est un test!\n\nProut?"); // Exit this script exit(0); ?> diff --git a/src/fixperms.sh b/src/fixperms.sh index 530c883a..58178d02 100755 --- a/src/fixperms.sh +++ b/src/fixperms.sh @@ -30,7 +30,8 @@ file="" # Two optionals argument # -l string : a specific login to fix # -u integer : a specific uid to fix -# -f integer : a specific file to fix according to a given uid +# -f string : a specific file to fix according to a given uid +# -d string : a specific folder to fix according to a given uid while getopts "l:u:f:d:" optname do @@ -118,6 +119,30 @@ doone() { echo -e "\nDone" } +fixdir() { + read GID LOGIN || true + if [ "$DEBUG" ]; then + echo "Setting rights and ownership for user $LOGIN having gid $GID" + fi + REP="$sub_dir" + + # Clean the line, then add a ligne indicating current working directory + printf '\r%*s' "${COLUMNS:-$(tput cols)}" '' + printf "\r%${COLUMNS}s" "AlternC fixperms.sh -> working on $REP" + + # Set the file readable only for the AlternC User + mkdir -p "$REP" + chown -R alterncpanel:$GID "$REP" + chmod 2770 -R "$REP" + + # Delete existings ACL + # Set the defaults acl on all the files + setfacl -b -k -n -R -m d:g:alterncpanel:rwx -m d:u::rwx -m d:g::rwx -m d:u:$GID:rwx -m d:g:$GID:rwx -m d:o::--- -m d:mask:rwx\ + -Rm g:alterncpanel:rwx -m u:$GID:rwx -m g:$GID:rwx -m mask:rwx\ + "$REP" + echo -e "\nDone" +} + fixfile() { read GID LOGIN /usr/bin/setfacl -bk "$file" @@ -129,12 +154,19 @@ fixfile() { echo file ownership and ACLs changed } + if [[ "$file" != "" ]]; then if [ -e "$file" ]; then mysql --defaults-file=/etc/alternc/my.cnf --skip-column-names -B -e "$query" |fixfile else echo "file not found" fi +elif [[ "$sub_dir" != "" ]]; then + if [ -d "$sub_dir" ]; then + mysql --defaults-file=/etc/alternc/my.cnf --skip-column-names -B -e "$query" |fixdir + else + echo "dir not found" + fi else mysql --defaults-file=/etc/alternc/my.cnf --skip-column-names -B -e "$query" |doone fi