/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/vt.h>

#include "sd-device.h"

#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
#include "cgroup-util.h"
#include "conf-parser.h"
#include "device-util.h"
#include "efi-loader.h"
#include "errno-util.h"
#include "fd-util.h"
#include "limits-util.h"
#include "logind.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
#include "stdio-util.h"
#include "strv.h"
#include "terminal-util.h"
#include "udev-util.h"
#include "user-util.h"
#include "userdb.h"
#include "utmp-wtmp.h"

void manager_reset_config(Manager *m) {
        assert(m);

        m->n_autovts = 6;
        m->reserve_vt = 6;
        m->remove_ipc = true;
        m->inhibit_delay_max = 5 * USEC_PER_SEC;
        m->user_stop_delay = 10 * USEC_PER_SEC;

        m->handle_power_key = HANDLE_POWEROFF;
        m->handle_power_key_long_press = HANDLE_IGNORE;
        m->handle_reboot_key = HANDLE_REBOOT;
        m->handle_reboot_key_long_press = HANDLE_POWEROFF;
        m->handle_suspend_key = HANDLE_SUSPEND;
        m->handle_suspend_key_long_press = HANDLE_HIBERNATE;
        m->handle_hibernate_key = HANDLE_HIBERNATE;
        m->handle_hibernate_key_long_press = HANDLE_IGNORE;

        m->handle_lid_switch = HANDLE_SUSPEND;
        m->handle_lid_switch_ep = _HANDLE_ACTION_INVALID;
        m->handle_lid_switch_docked = HANDLE_IGNORE;

        m->power_key_ignore_inhibited = false;
        m->suspend_key_ignore_inhibited = false;
        m->hibernate_key_ignore_inhibited = false;
        m->lid_switch_ignore_inhibited = true;
        m->reboot_key_ignore_inhibited = false;

        m->holdoff_timeout_usec = 30 * USEC_PER_SEC;

        m->idle_action_usec = 30 * USEC_PER_MINUTE;
        m->idle_action = HANDLE_IGNORE;

        m->runtime_dir_size = physical_memory_scale(10U, 100U); /* 10% */
        m->runtime_dir_inodes = DIV_ROUND_UP(m->runtime_dir_size, 4096); /* 4k per inode */
        m->sessions_max = 8192;
        m->inhibitors_max = 8192;

        m->kill_user_processes = KILL_USER_PROCESSES;

        m->kill_only_users = strv_free(m->kill_only_users);
        m->kill_exclude_users = strv_free(m->kill_exclude_users);

        m->stop_idle_session_usec = USEC_INFINITY;
}

int manager_parse_config_file(Manager *m) {
        assert(m);

        return config_parse_many_nulstr(
                        PKGSYSCONFDIR "/logind.conf",
                        CONF_PATHS_NULSTR("systemd/logind.conf.d"),
                        "Login\0",
                        config_item_perf_lookup, logind_gperf_lookup,
                        CONFIG_PARSE_WARN, m,
                        NULL);
}

int manager_add_device(Manager *m, const char *sysfs, bool master, Device **ret_device) {
        Device *d;

        assert(m);
        assert(sysfs);

        d = hashmap_get(m->devices, sysfs);
        if (d)
                /* we support adding master-flags, but not removing them */
                d->master = d->master || master;
        else {
                d = device_new(m, sysfs, master);
                if (!d)
                        return -ENOMEM;
        }

        if (ret_device)
                *ret_device = d;

        return 0;
}

int manager_add_seat(Manager *m, const char *id, Seat **ret_seat) {
        Seat *s;
        int r;

        assert(m);
        assert(id);

        s = hashmap_get(m->seats, id);
        if (!s) {
                r = seat_new(&s, m, id);
                if (r < 0)
                        return r;
        }

        if (ret_seat)
                *ret_seat = s;

        return 0;
}

int manager_add_session(Manager *m, const char *id, Session **ret_session) {
        Session *s;
        int r;

        assert(m);
        assert(id);

        s = hashmap_get(m->sessions, id);
        if (!s) {
                r = session_new(&s, m, id);
                if (r < 0)
                        return r;
        }

        if (ret_session)
                *ret_session = s;

        return 0;
}

int manager_add_user(
                Manager *m,
                UserRecord *ur,
                User **ret_user) {

        User *u;
        int r;

        assert(m);
        assert(ur);

        u = hashmap_get(m->users, UID_TO_PTR(ur->uid));
        if (!u) {
                r = user_new(&u, m, ur);
                if (r < 0)
                        return r;
        }

        if (ret_user)
                *ret_user = u;

        return 0;
}

int manager_add_user_by_name(
                Manager *m,
                const char *name,
                User **ret_user) {

        _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
        int r;

        assert(m);
        assert(name);

        r = userdb_by_name(name, USERDB_SUPPRESS_SHADOW, &ur);
        if (r < 0)
                return r;

        return manager_add_user(m, ur, ret_user);
}

int manager_add_user_by_uid(
                Manager *m,
                uid_t uid,
                User **ret_user) {

        _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
        int r;

        assert(m);
        assert(uid_is_valid(uid));

        r = userdb_by_uid(uid, USERDB_SUPPRESS_SHADOW, &ur);
        if (r < 0)
                return r;

        return manager_add_user(m, ur, ret_user);
}

int manager_add_inhibitor(Manager *m, const char* id, Inhibitor **ret) {
        Inhibitor *i;
        int r;

        assert(m);
        assert(id);

        i = hashmap_get(m->inhibitors, id);
        if (!i) {
                r = inhibitor_new(&i, m, id);
                if (r < 0)
                        return r;
        }

        if (ret)
                *ret = i;

        return 0;
}

int manager_add_button(Manager *m, const char *name, Button **ret_button) {
        Button *b;

        assert(m);
        assert(name);

        b = hashmap_get(m->buttons, name);
        if (!b) {
                b = button_new(m, name);
                if (!b)
                        return -ENOMEM;
        }

        if (ret_button)
                *ret_button = b;

        return 0;
}

int manager_process_seat_device(Manager *m, sd_device *d) {
        Device *device;
        int r;

        assert(m);

        if (device_for_action(d, SD_DEVICE_REMOVE) ||
            sd_device_has_current_tag(d, "seat") <= 0) {
                const char *syspath;

                r = sd_device_get_syspath(d, &syspath);
                if (r < 0)
                        return 0;

                device = hashmap_get(m->devices, syspath);
                if (!device)
                        return 0;

                seat_add_to_gc_queue(device->seat);
                device_free(device);

        } else {
                const char *sn, *syspath;
                bool master;
                Seat *seat;

                if (sd_device_get_property_value(d, "ID_SEAT", &sn) < 0 || isempty(sn))
                        sn = "seat0";

                if (!seat_name_is_valid(sn)) {
                        log_device_warning(d, "Device with invalid seat name %s found, ignoring.", sn);
                        return 0;
                }

                seat = hashmap_get(m->seats, sn);
                master = sd_device_has_current_tag(d, "master-of-seat") > 0;

                /* Ignore non-master devices for unknown seats */
                if (!master && !seat)
                        return 0;

                r = sd_device_get_syspath(d, &syspath);
                if (r < 0)
                        return r;

                r = manager_add_device(m, syspath, master, &device);
                if (r < 0)
                        return r;

                if (!seat) {
                        r = manager_add_seat(m, sn, &seat);
                        if (r < 0) {
                                if (!device->seat)
                                        device_free(device);

                                return r;
                        }
                }

                device_attach(device, seat);
                seat_start(seat);
        }

        return 0;
}

int manager_process_button_device(Manager *m, sd_device *d) {
        const char *sysname;
        Button *b;
        int r;

        assert(m);

        r = sd_device_get_sysname(d, &sysname);
        if (r < 0)
                return r;

        if (device_for_action(d, SD_DEVICE_REMOVE) ||
            sd_device_has_current_tag(d, "power-switch") <= 0) {

                b = hashmap_get(m->buttons, sysname);
                if (!b)
                        return 0;

                button_free(b);

        } else {
                const char *sn;

                r = manager_add_button(m, sysname, &b);
                if (r < 0)
                        return r;

                if (sd_device_get_property_value(d, "ID_SEAT", &sn) < 0 || isempty(sn))
                        sn = "seat0";

                button_set_seat(b, sn);

                r = button_open(b);
                if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error
                            * opening the device?) let's close the button again. */
                        button_free(b);
        }

        return 0;
}

int manager_get_session_by_pid(Manager *m, pid_t pid, Session **ret) {
        _cleanup_free_ char *unit = NULL;
        Session *s;
        int r;

        assert(m);

        if (!pid_is_valid(pid))
                return -EINVAL;

        s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(pid));
        if (!s) {
                r = cg_pid_get_unit(pid, &unit);
                if (r >= 0)
                        s = hashmap_get(m->session_units, unit);
        }

        if (ret)
                *ret = s;

        return !!s;
}

int manager_get_user_by_pid(Manager *m, pid_t pid, User **ret) {
        _cleanup_free_ char *unit = NULL;
        User *u = NULL;
        int r;

        assert(m);

        if (!pid_is_valid(pid))
                return -EINVAL;

        r = cg_pid_get_slice(pid, &unit);
        if (r >= 0)
                u = hashmap_get(m->user_units, unit);

        if (ret)
                *ret = u;

        return !!u;
}

int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
        Session *s;
        bool idle_hint;
        dual_timestamp ts = DUAL_TIMESTAMP_NULL;

        assert(m);

        idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0, NULL);

        HASHMAP_FOREACH(s, m->sessions) {
                dual_timestamp k;
                int ih;

                ih = session_get_idle_hint(s, &k);
                if (ih < 0)
                        return ih;

                if (!ih) {
                        if (!idle_hint) {
                                if (k.monotonic < ts.monotonic)
                                        ts = k;
                        } else {
                                idle_hint = false;
                                ts = k;
                        }
                } else if (idle_hint) {

                        if (k.monotonic > ts.monotonic)
                                ts = k;
                }
        }

        if (t)
                *t = ts;

        return idle_hint;
}

bool manager_shall_kill(Manager *m, const char *user) {
        assert(m);
        assert(user);

        if (!m->kill_exclude_users && streq(user, "root"))
                return false;

        if (strv_contains(m->kill_exclude_users, user))
                return false;

        if (!strv_isempty(m->kill_only_users))
                return strv_contains(m->kill_only_users, user);

        return m->kill_user_processes;
}

int config_parse_n_autovts(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        unsigned *n = ASSERT_PTR(data);
        unsigned o;
        int r;

        assert(filename);
        assert(lvalue);
        assert(rvalue);

        r = safe_atou(rvalue, &o);
        if (r < 0) {
                log_syntax(unit, LOG_WARNING, filename, line, r,
                           "Failed to parse number of autovts, ignoring: %s", rvalue);
                return 0;
        }

        if (o > 15) {
                log_syntax(unit, LOG_WARNING, filename, line, 0,
                           "A maximum of 15 autovts are supported, ignoring: %s", rvalue);
                return 0;
        }

        *n = o;
        return 0;
}

static int vt_is_busy(unsigned vtnr) {
        struct vt_stat vt_stat;
        int r;
        _cleanup_close_ int fd = -EBADF;

        assert(vtnr >= 1);

        /* VT_GETSTATE "cannot return state for more than 16 VTs, since v_state is short" */
        assert(vtnr <= 15);

        /* We explicitly open /dev/tty1 here instead of /dev/tty0. If
         * we'd open the latter we'd open the foreground tty which
         * hence would be unconditionally busy. By opening /dev/tty1
         * we avoid this. Since tty1 is special and needs to be an
         * explicitly loaded getty or DM this is safe. */

        fd = open_terminal("/dev/tty1", O_RDWR|O_NOCTTY|O_CLOEXEC);
        if (fd < 0)
                return -errno;

        if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
                r = -errno;
        else
                r = !!(vt_stat.v_state & (1 << vtnr));

        return r;
}

int manager_spawn_autovt(Manager *m, unsigned vtnr) {
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        char name[sizeof("autovt@tty.service") + DECIMAL_STR_MAX(unsigned)];
        int r;

        assert(m);
        assert(vtnr >= 1);

        if (vtnr > m->n_autovts &&
            vtnr != m->reserve_vt)
                return 0;

        if (vtnr != m->reserve_vt) {
                /* If this is the reserved TTY, we'll start the getty
                 * on it in any case, but otherwise only if it is not
                 * busy. */

                r = vt_is_busy(vtnr);
                if (r < 0)
                        return r;
                else if (r > 0)
                        return -EBUSY;
        }

        xsprintf(name, "autovt@tty%u.service", vtnr);
        r = sd_bus_call_method(
                        m->bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        "org.freedesktop.systemd1.Manager",
                        "StartUnit",
                        &error,
                        NULL,
                        "ss", name, "fail");
        if (r < 0)
                return log_error_errno(r, "Failed to start %s: %s", name, bus_error_message(&error, r));

        return 0;
}

bool manager_is_lid_closed(Manager *m) {
        Button *b;

        HASHMAP_FOREACH(b, m->buttons)
                if (b->lid_closed)
                        return true;

        return false;
}

static bool manager_is_docked(Manager *m) {
        Button *b;

        HASHMAP_FOREACH(b, m->buttons)
                if (b->docked)
                        return true;

        return false;
}

static int manager_count_external_displays(Manager *m) {
        _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
        sd_device *d;
        int r, n = 0;

        r = sd_device_enumerator_new(&e);
        if (r < 0)
                return r;

        r = sd_device_enumerator_allow_uninitialized(e);
        if (r < 0)
                return r;

        r = sd_device_enumerator_add_match_subsystem(e, "drm", true);
        if (r < 0)
                return r;

        FOREACH_DEVICE(e, d) {
                const char *status, *enabled, *dash, *nn, *subsys;
                sd_device *p;

                if (sd_device_get_parent(d, &p) < 0)
                        continue;

                /* If the parent shares the same subsystem as the
                 * device we are looking at then it is a connector,
                 * which is what we are interested in. */
                if (sd_device_get_subsystem(p, &subsys) < 0 || !streq(subsys, "drm"))
                        continue;

                if (sd_device_get_sysname(d, &nn) < 0)
                        continue;

                /* Ignore internal displays: the type is encoded in the sysfs name, as the second dash
                 * separated item (the first is the card name, the last the connector number). We implement a
                 * deny list of external displays here, rather than an allow list of internal ones, to ensure
                 * we don't block suspends too eagerly. */
                dash = strchr(nn, '-');
                if (!dash)
                        continue;

                dash++;
                if (!STARTSWITH_SET(dash,
                                    "VGA-", "DVI-I-", "DVI-D-", "DVI-A-"
                                    "Composite-", "SVIDEO-", "Component-",
                                    "DIN-", "DP-", "HDMI-A-", "HDMI-B-", "TV-"))
                        continue;

                /* Ignore ports that are not enabled */
                if (sd_device_get_sysattr_value(d, "enabled", &enabled) < 0 || !streq(enabled, "enabled"))
                        continue;

                /* We count any connector which is not explicitly
                 * "disconnected" as connected. */
                if (sd_device_get_sysattr_value(d, "status", &status) < 0 || !streq(status, "disconnected"))
                        n++;
        }

        return n;
}

bool manager_is_docked_or_external_displays(Manager *m) {
        int n;

        /* If we are docked don't react to lid closing */
        if (manager_is_docked(m)) {
                log_debug("System is docked.");
                return true;
        }

        /* If we have more than one display connected,
         * assume that we are docked. */
        n = manager_count_external_displays(m);
        if (n < 0)
                log_warning_errno(n, "Display counting failed: %m");
        else if (n >= 1) {
                log_debug("External (%i) displays connected.", n);
                return true;
        }

        return false;
}

bool manager_is_on_external_power(void) {
        int r;

        /* For now we only check for AC power, but 'external power' can apply to anything that isn't an internal
         * battery */
        r = on_ac_power();
        if (r < 0)
                log_warning_errno(r, "Failed to read AC power status: %m");

        return r != 0; /* Treat failure as 'on AC' */
}

bool manager_all_buttons_ignored(Manager *m) {
        assert(m);

        if (m->handle_power_key != HANDLE_IGNORE)
                return false;
        if (m->handle_power_key_long_press != HANDLE_IGNORE)
                return false;
        if (m->handle_suspend_key != HANDLE_IGNORE)
                return false;
        if (m->handle_suspend_key_long_press != HANDLE_IGNORE)
                return false;
        if (m->handle_hibernate_key != HANDLE_IGNORE)
                return false;
        if (m->handle_hibernate_key_long_press != HANDLE_IGNORE)
                return false;
        if (m->handle_reboot_key != HANDLE_IGNORE)
                return false;
        if (m->handle_reboot_key_long_press != HANDLE_IGNORE)
                return false;
        if (m->handle_lid_switch != HANDLE_IGNORE)
                return false;
        if (!IN_SET(m->handle_lid_switch_ep, _HANDLE_ACTION_INVALID, HANDLE_IGNORE))
                return false;
        if (m->handle_lid_switch_docked != HANDLE_IGNORE)
                return false;

        return true;
}

int manager_read_utmp(Manager *m) {
#if ENABLE_UTMP
        int r;
        _unused_ _cleanup_(utxent_cleanup) bool utmpx = false;

        assert(m);

        if (utmpxname(_PATH_UTMPX) < 0)
                return log_error_errno(errno, "Failed to set utmp path to " _PATH_UTMPX ": %m");

        utmpx = utxent_start();

        for (;;) {
                _cleanup_free_ char *t = NULL;
                struct utmpx *u;
                const char *c;
                Session *s;

                errno = 0;
                u = getutxent();
                if (!u) {
                        if (errno == ENOENT)
                                log_debug_errno(errno, _PATH_UTMPX " does not exist, ignoring.");
                        else if (errno != 0)
                                log_warning_errno(errno, "Failed to read " _PATH_UTMPX ", ignoring: %m");
                        return 0;
                }

                if (u->ut_type != USER_PROCESS)
                        continue;

                if (!pid_is_valid(u->ut_pid))
                        continue;

                t = strndup(u->ut_line, sizeof(u->ut_line));
                if (!t)
                        return log_oom();

                c = path_startswith(t, "/dev/");
                if (c) {
                        r = free_and_strdup(&t, c);
                        if (r < 0)
                                return log_oom();
                }

                if (isempty(t))
                        continue;

                s = hashmap_get(m->sessions_by_leader, PID_TO_PTR(u->ut_pid));
                if (!s)
                        continue;

                if (s->tty_validity == TTY_FROM_UTMP && !streq_ptr(s->tty, t)) {
                        /* This may happen on multiplexed SSH connection (i.e. 'SSH connection sharing'). In
                         * this case PAM and utmp sessions don't match. In such a case let's invalidate the TTY
                         * information and never acquire it again. */

                        s->tty = mfree(s->tty);
                        s->tty_validity = TTY_UTMP_INCONSISTENT;
                        log_debug("Session '%s' has inconsistent TTY information, dropping TTY information.", s->id);
                        continue;
                }

                /* Never override what we figured out once */
                if (s->tty || s->tty_validity >= 0)
                        continue;

                s->tty = TAKE_PTR(t);
                s->tty_validity = TTY_FROM_UTMP;
                log_debug("Acquired TTY information '%s' from utmp for session '%s'.", s->tty, s->id);
        }

#else
        return 0;
#endif
}

#if ENABLE_UTMP
static int manager_dispatch_utmp(sd_event_source *s, const struct inotify_event *event, void *userdata) {
        Manager *m = ASSERT_PTR(userdata);

        /* If there's indication the file itself might have been removed or became otherwise unavailable, then let's
         * reestablish the watch on whatever there's now. */
        if ((event->mask & (IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF|IN_Q_OVERFLOW|IN_UNMOUNT)) != 0)
                manager_connect_utmp(m);

        (void) manager_read_utmp(m);
        return 0;
}
#endif

void manager_connect_utmp(Manager *m) {
#if ENABLE_UTMP
        sd_event_source *s = NULL;
        int r;

        assert(m);

        /* Watch utmp for changes via inotify. We do this to deal with tools such as ssh, which will register the PAM
         * session early, and acquire a TTY only much later for the connection. Thus during PAM the TTY won't be known
         * yet. ssh will register itself with utmp when it finally acquired the TTY. Hence, let's make use of this, and
         * watch utmp for the TTY asynchronously. We use the PAM session's leader PID as key, to find the right entry.
         *
         * Yes, relying on utmp is pretty ugly, but it's good enough for informational purposes, as well as idle
         * detection (which, for tty sessions, relies on the TTY used) */

        r = sd_event_add_inotify(m->event, &s, _PATH_UTMPX, IN_MODIFY|IN_MOVE_SELF|IN_DELETE_SELF|IN_ATTRIB, manager_dispatch_utmp, m);
        if (r < 0)
                log_full_errno(r == -ENOENT ? LOG_DEBUG: LOG_WARNING, r, "Failed to create inotify watch on " _PATH_UTMPX ", ignoring: %m");
        else {
                r = sd_event_source_set_priority(s, SD_EVENT_PRIORITY_IDLE);
                if (r < 0)
                        log_warning_errno(r, "Failed to adjust utmp event source priority, ignoring: %m");

                (void) sd_event_source_set_description(s, "utmp");
        }

        sd_event_source_unref(m->utmp_event_source);
        m->utmp_event_source = s;
#endif
}

void manager_reconnect_utmp(Manager *m) {
#if ENABLE_UTMP
        assert(m);

        if (m->utmp_event_source)
                return;

        manager_connect_utmp(m);
#endif
}

int manager_read_efi_boot_loader_entries(Manager *m) {
#if ENABLE_EFI
        int r;

        assert(m);
        if (m->efi_boot_loader_entries_set)
                return 0;

        r = efi_loader_get_entries(&m->efi_boot_loader_entries);
        if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r)) {
                log_debug_errno(r, "Boot loader reported no entries.");
                m->efi_boot_loader_entries_set = true;
                return 0;
        }
        if (r < 0)
                return log_error_errno(r, "Failed to determine entries reported by boot loader: %m");

        m->efi_boot_loader_entries_set = true;
        return 1;
#else
        return 0;
#endif
}
