1<?php 2/** 3 * Checks.php 4 * 5 * Pre-flight checks at various stages of booting 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <https://www.gnu.org/licenses/>. 19 * 20 * @link https://www.librenms.org 21 * @copyright 2018 Tony Murray 22 * @author Tony Murray <murraytony@gmail.com> 23 */ 24 25namespace App; 26 27use App\Models\Device; 28use App\Models\Notification; 29use Cache; 30use Carbon\Carbon; 31use Illuminate\Support\Facades\Auth; 32use LibreNMS\Config; 33use Toastr; 34 35class Checks 36{ 37 /** 38 * Post boot Toast messages 39 */ 40 public static function postAuth() 41 { 42 // limit popup messages frequency 43 if (Cache::get('checks_popup_timeout') || ! Auth::check()) { 44 return; 45 } 46 47 Cache::put('checks_popup_timeout', true, Config::get('checks_popup_timer', 5) * 60); 48 49 $user = Auth::user(); 50 51 if ($user->isAdmin()) { 52 $notifications = Notification::isUnread($user)->where('severity', '>', \LibreNMS\Enum\Alert::OK)->get(); 53 foreach ($notifications as $notification) { 54 Toastr::error("<a href='notifications/'>$notification->body</a>", $notification->title); 55 } 56 57 $warn_sec = Config::get('rrd.step', 300) * 3; 58 if (Device::isUp()->where('last_polled', '<=', Carbon::now()->subSeconds($warn_sec))->exists()) { 59 $warn_min = $warn_sec / 60; 60 Toastr::warning('<a href="poller/log?filter=unpolled/">It appears as though you have some devices that haven\'t completed polling within the last ' . $warn_min . ' minutes, you may want to check that out :)</a>', 'Devices unpolled'); 61 } 62 63 // Directory access checks 64 $rrd_dir = Config::get('rrd_dir'); 65 if (! is_dir($rrd_dir)) { 66 Toastr::error("RRD Directory is missing ($rrd_dir). Graphing may fail. <a href=" . url('validate') . '>Validate your install</a>'); 67 } 68 69 $temp_dir = Config::get('temp_dir'); 70 if (! is_dir($temp_dir)) { 71 Toastr::error("Temp Directory is missing ($temp_dir). Graphing may fail. <a href=" . url('validate') . '>Validate your install</a>'); 72 } elseif (! is_writable($temp_dir)) { 73 Toastr::error("Temp Directory is not writable ($temp_dir). Graphing may fail. <a href='" . url('validate') . "'>Validate your install</a>"); 74 } 75 } 76 } 77 78 /** 79 * Check the script is running as the right user (works before config is available) 80 */ 81 public static function runningUser() 82 { 83 if (function_exists('posix_getpwuid') && posix_getpwuid(posix_geteuid())['name'] !== get_current_user()) { 84 if (get_current_user() == 'root') { 85 self::printMessage( 86 'Error: lnms file is owned by root, it should be owned and ran by a non-privileged user.', 87 null, 88 true 89 ); 90 } 91 92 self::printMessage( 93 'Error: You must run lnms as the user ' . get_current_user(), 94 null, 95 true 96 ); 97 } 98 } 99 100 private static function printMessage($title, $content, $exit = false) 101 { 102 $content = (array) $content; 103 104 if (PHP_SAPI == 'cli') { 105 $format = "%s\n\n%s\n\n"; 106 $message = implode(PHP_EOL, $content); 107 } else { 108 $format = "<h3 style='color: firebrick;'>%s</h3><p>%s</p>"; 109 $message = ''; 110 foreach ($content as $line) { 111 $message .= "<p style='margin:0.5em'>$line</p>\n"; 112 } 113 } 114 115 printf($format, $title, $message); 116 117 if ($exit) { 118 exit(1); 119 } 120 } 121} 122