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