logind-dbus.c revision b9c26b413497a0014ac2058a0ec04849a83df1ea
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering/***
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering This file is part of systemd.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Copyright 2011 Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering (at your option) any later version.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering systemd is distributed in the hope that it will be useful, but
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Lesser General Public License for more details.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering***/
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <errno.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <string.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include <unistd.h>
96115cdfe0241ae9b4e7177cd3874c0a93d00b39Thomas Hindoe Paaboel Andersen#include <pwd.h>
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#include "logind.h"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#include "dbus-common.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "strv.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "mkdir.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "path-util.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#include "polkit.h"
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek#include "special.h"
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#define BUS_MANAGER_INTERFACE \
9a5cb1371b6d8b0a04bd08665bcf9b06cb40c64cZbigniew Jędrzejewski-Szmek " <interface name=\"org.freedesktop.login1.Manager\">\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <method name=\"GetSession\">\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"session\" type=\"o\" direction=\"out\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " </method>\n" \
1b9e5b126359a2a2ec37de1f94f046093abc74b8Lennart Poettering " <method name=\"GetSessionByPID\">\n" \
f9ac15442e4132f00eca5495d53c17062aae13e0Lennart Poettering " <arg name=\"pid\" type=\"u\" direction=\"in\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <arg name=\"session\" type=\"o\" direction=\"out\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " </method>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <method name=\"GetUser\">\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <arg name=\"user\" type=\"o\" direction=\"out\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " </method>\n" \
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering " <method name=\"GetSeat\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"seat\" type=\"o\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"ListSessions\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"sessions\" type=\"a(susso)\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"ListUsers\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"users\" type=\"a(uso)\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " <method name=\"ListSeats\">\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " <arg name=\"seats\" type=\"a(so)\" direction=\"out\"/>\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"CreateSession\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"leader\" type=\"u\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"sevice\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"type\" type=\"s\" direction=\"in\"/>\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " <arg name=\"class\" type=\"s\" direction=\"in\"/>\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " <arg name=\"seat\" type=\"s\" direction=\"in\"/>\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " <arg name=\"vtnr\" type=\"u\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"tty\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"display\" type=\"s\" direction=\"in\"/>\n" \
821b2e792159e237a1e5a1ea4bb6ae2e55d64be5Lukas Nykryn " <arg name=\"remote\" type=\"b\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"remote_user\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"remote_host\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"controllers\" type=\"as\" direction=\"in\"/>\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <arg name=\"reset_controllers\" type=\"as\" direction=\"in\"/>\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <arg name=\"kill_processes\" type=\"b\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"path\" type=\"o\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"runtime_path\" type=\"o\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"fd\" type=\"h\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"seat\" type=\"s\" direction=\"out\"/>\n" \
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering " <arg name=\"vtnr\" type=\"u\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"ReleaseSession\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"ActivateSession\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"ActivateSessionOnSeat\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"seat\" type=\"s\" direction=\"in\"/>\n" \
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"LockSession\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"UnlockSession\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering " </method>\n" \
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering " <method name=\"LockSessions\"/>\n" \
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering " <method name=\"KillSession\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering " <arg name=\"who\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"signal\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"KillUser\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"signal\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <method name=\"TerminateSession\">\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"TerminateUser\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"TerminateSeat\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <method name=\"SetUserLinger\">\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <arg name=\"uid\" type=\"u\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"b\" type=\"b\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"AttachDevice\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"seat\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"sysfs\" type=\"s\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " </method>\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <method name=\"FlushDevices\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"PowerOff\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"Reboot\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"Suspend\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
4c1fc3e404d648c70bd2f50ac50aeac6ece8872eDaniel Mack " </method>\n" \
4c1fc3e404d648c70bd2f50ac50aeac6ece8872eDaniel Mack " <method name=\"Hibernate\">\n" \
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt " <arg name=\"interactive\" type=\"b\" direction=\"in\"/>\n" \
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"CanPowerOff\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"result\" type=\"s\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"CanReboot\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"result\" type=\"s\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"CanSuspend\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"result\" type=\"s\" direction=\"out\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </method>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <method name=\"CanHibernate\">\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <arg name=\"result\" type=\"s\" direction=\"out\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " </method>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <method name=\"Inhibit\">\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <arg name=\"what\" type=\"s\" direction=\"in\"/>\n" \
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering " <arg name=\"who\" type=\"s\" direction=\"in\"/>\n" \
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers " <arg name=\"why\" type=\"s\" direction=\"in\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <arg name=\"mode\" type=\"s\" direction=\"in\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <arg name=\"fd\" type=\"h\" direction=\"out\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " </method>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <method name=\"ListInhibitors\">\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <arg name=\"inhibitors\" type=\"a(ssssuu)\" direction=\"out\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " </method>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <signal name=\"SessionNew\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"path\" type=\"o\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </signal>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <signal name=\"SessionRemoved\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <arg name=\"path\" type=\"o\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " </signal>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <signal name=\"UserNew\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"uid\" type=\"u\"/>\n" \
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering " <arg name=\"path\" type=\"o\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </signal>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <signal name=\"UserRemoved\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"uid\" type=\"u\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"path\" type=\"o\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </signal>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <signal name=\"SeatNew\">\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " <arg name=\"id\" type=\"s\"/>\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " <arg name=\"path\" type=\"o\"/>\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " </signal>\n" \
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering " <signal name=\"SeatRemoved\">\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <arg name=\"id\" type=\"s\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <arg name=\"path\" type=\"o\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " </signal>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <signal name=\"PrepareForShutdown\">\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <arg name=\"active\" type=\"b\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " </signal>\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <signal name=\"PrepareForSleep\">\n" \
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt " <arg name=\"active\" type=\"b\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " </signal>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <property name=\"ControlGroupHierarchy\" type=\"s\" access=\"read\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <property name=\"Controllers\" type=\"as\" access=\"read\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <property name=\"ResetControllers\" type=\"as\" access=\"read\"/>\n" \
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering " <property name=\"NAutoVTs\" type=\"u\" access=\"read\"/>\n" \
c3834f9b881f2b1a68dc7d797c134f0b66b47b57Lennart Poettering " <property name=\"KillOnlyUsers\" type=\"as\" access=\"read\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <property name=\"KillExcludeUsers\" type=\"as\" access=\"read\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <property name=\"KillUserProcesses\" type=\"b\" access=\"read\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <property name=\"IdleHint\" type=\"b\" access=\"read\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <property name=\"IdleSinceHint\" type=\"t\" access=\"read\"/>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering " <property name=\"IdleSinceHintMonotonic\" type=\"t\" access=\"read\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <property name=\"BlockInhibited\" type=\"s\" access=\"read\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <property name=\"DelayInhibited\" type=\"s\" access=\"read\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <property name=\"InhibitDelayMaxUSec\" type=\"t\" access=\"read\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <property name=\"HandlePowerKey\" type=\"s\" access=\"read\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <property name=\"HandleSleepKey\" type=\"s\" access=\"read\"/>\n" \
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering " <property name=\"HandleLidSwitch\" type=\"s\" access=\"read\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <property name=\"PreparingForShutdown\" type=\"b\" access=\"read\"/>\n" \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering " <property name=\"PreparingForSleep\" type=\"b\" access=\"read\"/>\n" \
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering " </interface>\n"
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering
1af7211984a8dba3c5ba40fae794c4c55f5e6bd3Lennart Poettering#define INTROSPECTION_BEGIN \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "<node>\n" \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering BUS_MANAGER_INTERFACE \
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers BUS_PROPERTIES_INTERFACE \
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers BUS_PEER_INTERFACE \
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers BUS_INTROSPECTABLE_INTERFACE
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering#define INTROSPECTION_END \
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering "</node>\n"
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering#define INTERFACES_LIST \
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering BUS_GENERIC_INTERFACES_LIST \
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering "org.freedesktop.login1.Manager\0"
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int bus_manager_append_idle_hint(DBusMessageIter *i, const char *property, void *data) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering Manager *m = data;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering dbus_bool_t b;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt assert(i);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt assert(property);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering assert(m);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering b = manager_get_idle_hint(m, NULL) > 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return -ENOMEM;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers}
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversstatic int bus_manager_append_idle_hint_since(DBusMessageIter *i, const char *property, void *data) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers Manager *m = data;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dual_timestamp t;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers uint64_t u;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(i);
1ae2285324e01dc3a2d44d7b1711b939261cc756Thomas Hindoe Paaboel Andersen assert(property);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(m);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers manager_get_idle_hint(m, &t);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers u = streq(property, "IdleSinceHint") ? t.realtime : t.monotonic;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -ENOMEM;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers}
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversstatic int bus_manager_append_inhibited(DBusMessageIter *i, const char *property, void *data) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers Manager *m = data;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers InhibitWhat w;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers const char *p;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers w = manager_inhibit_what(m, streq(property, "BlockInhibited") ? INHIBIT_BLOCK : INHIBIT_DELAY);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers p = inhibit_what_to_string(w);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &p))
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -ENOMEM;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers}
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversstatic int bus_manager_append_preparing(DBusMessageIter *i, const char *property, void *data) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers Manager *m = data;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_bool_t b;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(i);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(property);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (streq(property, "PreparingForShutdown"))
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers b = !!(m->delayed_what & INHIBIT_SHUTDOWN);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers else
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers b = !!(m->delayed_what & INHIBIT_SLEEP);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers}
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sieversstatic int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMessage **_reply) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers Session *session = NULL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers User *user = NULL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers const char *type, *class, *seat, *tty, *display, *remote_user, *remote_host, *service;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers uint32_t uid, leader, audit_id = 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_bool_t remote, kill_processes;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers char **controllers = NULL, **reset_controllers = NULL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers SessionType t;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers SessionClass c;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering Seat *s;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering DBusMessageIter iter;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering int r;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers char *id = NULL, *p;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers uint32_t vtnr = 0;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers int fifo_fd = -1;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers DBusMessage *reply = NULL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers bool b;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(m);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(message);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(_reply);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_init(message, &iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_basic(&iter, &uid);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_basic(&iter, &leader);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (leader <= 0 ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers !dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_basic(&iter, &service);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_basic(&iter, &type);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering t = session_type_from_string(type);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (t < 0 ||
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering !dbus_message_iter_next(&iter) ||
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -EINVAL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering dbus_message_iter_get_basic(&iter, &class);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (isempty(class))
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek c = SESSION_USER;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering else
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering c = session_class_from_string(class);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (c < 0 ||
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering !dbus_message_iter_next(&iter) ||
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering dbus_message_iter_get_basic(&iter, &seat);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (isempty(seat))
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering s = NULL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering else {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering s = hashmap_get(m->seats, seat);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!s)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -ENOENT;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!dbus_message_iter_next(&iter) ||
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt return -EINVAL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering dbus_message_iter_get_basic(&iter, &vtnr);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!dbus_message_iter_next(&iter) ||
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -EINVAL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering dbus_message_iter_get_basic(&iter, &tty);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (tty_is_vc(tty)) {
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek int v;
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!s)
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek s = m->vtconsole;
a0b1209c4a59754f428894e0485413542da50014Zbigniew Jędrzejewski-Szmek else if (s != m->vtconsole)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -EINVAL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering v = vtnr_from_tty(tty);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (v <= 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return v < 0 ? v : -EINVAL;
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (vtnr <= 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering vtnr = (uint32_t) v;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering else if (vtnr != (uint32_t) v)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return -EINVAL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering } else if (tty_is_console(tty)) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!s)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers s = m->vtconsole;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers else if (s != m->vtconsole)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (vtnr != 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers } else if (!isempty(tty) && s && seat_is_vtconsole(s))
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (s) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (seat_can_multi_session(s)) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (vtnr > 63)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers } else {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (vtnr != 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_basic(&iter, &display);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return -EINVAL;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering dbus_message_iter_get_basic(&iter, &remote);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_basic(&iter, &remote_user);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_basic(&iter, &remote_host);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = bus_parse_strv_iter(&iter, &controllers);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers return -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (strv_contains(controllers, "systemd") ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers !dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = bus_parse_strv_iter(&iter, &reset_controllers);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (strv_contains(reset_controllers, "systemd") ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers !dbus_message_iter_next(&iter) ||
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers dbus_message_iter_get_basic(&iter, &kill_processes);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = manager_add_user_by_uid(m, uid, &user);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (r < 0)
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers audit_session_from_pid(leader, &audit_id);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (audit_id > 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers asprintf(&id, "%lu", (unsigned long) audit_id);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!id) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = -ENOMEM;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers session = hashmap_get(m->sessions, id);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (session) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers free(id);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers fifo_fd = session_create_fifo(session);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (fifo_fd < 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = fifo_fd;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers /* Session already exists, client is probably
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers * something like "su" which changes uid but
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers * is still the same audit session */
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers reply = dbus_message_new_method_return(message);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!reply) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = -ENOMEM;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers p = session_bus_path(session);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!p) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = -ENOMEM;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers seat = session->seat ? session->seat->id : "";
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers vtnr = session->vtnr;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers b = dbus_message_append_args(
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers reply,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers DBUS_TYPE_STRING, &session->id,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers DBUS_TYPE_OBJECT_PATH, &p,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers DBUS_TYPE_STRING, &session->user->runtime_path,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers DBUS_TYPE_UNIX_FD, &fifo_fd,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers DBUS_TYPE_STRING, &seat,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers DBUS_TYPE_UINT32, &vtnr,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers DBUS_TYPE_INVALID);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers free(p);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (!b) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = -ENOMEM;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers close_nointr_nofail(fifo_fd);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers *_reply = reply;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers strv_free(controllers);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers strv_free(reset_controllers);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering return 0;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek } else {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering do {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering free(id);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers id = NULL;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (asprintf(&id, "c%lu", ++m->session_counter) < 0) {
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek r = -ENOMEM;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering } while (hashmap_get(m->sessions, id));
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = manager_add_session(m, user, id, &session);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering free(id);
b47d419c25ecc735615a1088060c1ec8bef1e41fZbigniew Jędrzejewski-Szmek if (r < 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek session->leader = leader;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek session->audit_id = audit_id;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering session->type = t;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek session->class = c;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek session->remote = remote;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek session->controllers = controllers;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek session->reset_controllers = reset_controllers;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek session->kill_processes = kill_processes;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek session->vtnr = vtnr;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek controllers = reset_controllers = NULL;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!isempty(tty)) {
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering session->tty = strdup(tty);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek if (!session->tty) {
9c4495ca561624c2f0085507dd1288ed5f1247c5Tomasz Torcz r = -ENOMEM;
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering goto fail;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering if (!isempty(display)) {
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek session->display = strdup(display);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!session->display) {
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering r = -ENOMEM;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering }
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!isempty(remote_user)) {
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering session->remote_user = strdup(remote_user);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!session->remote_user) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = -ENOMEM;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering goto fail;
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering }
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering if (!isempty(remote_host)) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering session->remote_host = strdup(remote_host);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek if (!session->remote_host) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = -ENOMEM;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!isempty(service)) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering session->service = strdup(service);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!session->service) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = -ENOMEM;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering fifo_fd = session_create_fifo(session);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (fifo_fd < 0) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = fifo_fd;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (s) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = seat_attach_session(s, session);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek if (r < 0)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = session_start(session);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek if (r < 0)
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek goto fail;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering reply = dbus_message_new_method_return(message);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!reply) {
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering r = -ENOMEM;
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
fa041593fe04b12ffd7e81d8b3598a7a6f313fb3Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering p = session_bus_path(session);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!p) {
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering r = -ENOMEM;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering seat = s ? s->id : "";
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek b = dbus_message_append_args(
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering reply,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering DBUS_TYPE_STRING, &session->id,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering DBUS_TYPE_OBJECT_PATH, &p,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering DBUS_TYPE_STRING, &session->user->runtime_path,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering DBUS_TYPE_UNIX_FD, &fifo_fd,
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering DBUS_TYPE_STRING, &seat,
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering DBUS_TYPE_UINT32, &vtnr,
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek DBUS_TYPE_INVALID);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek free(p);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!b) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek r = -ENOMEM;
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek goto fail;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt close_nointr_nofail(fifo_fd);
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek *_reply = reply;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poetteringfail:
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering strv_free(controllers);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering strv_free(reset_controllers);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (session)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering session_add_to_gc_queue(session);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (user)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek user_add_to_gc_queue(user);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (fifo_fd >= 0)
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering close_nointr_nofail(fifo_fd);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (reply)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering dbus_message_unref(reply);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek return r;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering}
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poetteringstatic int bus_manager_inhibit(Manager *m, DBusConnection *connection, DBusMessage *message, DBusError *error, DBusMessage **_reply) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering Inhibitor *i = NULL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering char *id = NULL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering const char *who, *why, *what, *mode;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering pid_t pid;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering InhibitWhat w;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering InhibitMode mm;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering unsigned long ul;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering int r, fifo_fd = -1;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering DBusMessage *reply = NULL;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering assert(m);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering assert(connection);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering assert(message);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering assert(error);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering assert(_reply);
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering if (!dbus_message_get_args(
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering message,
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek error,
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering DBUS_TYPE_STRING, &what,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering DBUS_TYPE_STRING, &who,
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers DBUS_TYPE_STRING, &why,
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers DBUS_TYPE_STRING, &mode,
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers DBUS_TYPE_INVALID)) {
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers r = -EIO;
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers goto fail;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek w = inhibit_what_from_string(what);
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering if (w <= 0) {
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering r = -EINVAL;
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering goto fail;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering mm = inhibit_mode_from_string(mode);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (mm < 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = -EINVAL;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = verify_polkit(connection, message,
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers m == INHIBIT_BLOCK ?
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "org.freedesktop.login1.inhibit-block" :
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers "org.freedesktop.login1.inhibit-delay", false, NULL, error);
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack if (r < 0)
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (ul == (unsigned long) -1) {
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers r = -EIO;
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers goto fail;
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers }
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers pid = bus_get_unix_process_id(connection, dbus_message_get_sender(message), error);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (pid <= 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering r = -EIO;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering goto fail;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering do {
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering free(id);
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering id = NULL;
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack if (asprintf(&id, "%lu", ++m->inhibit_counter) < 0) {
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering r = -ENOMEM;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering goto fail;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers } while (hashmap_get(m->inhibitors, id));
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers r = manager_add_inhibitor(m, id, &i);
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers free(id);
0238d4c660e732dd03ba0cdb54a29ec5870ee849Kay Sievers
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (r < 0)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering goto fail;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering i->what = w;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering i->mode = mm;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering i->pid = pid;
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering i->uid = (uid_t) ul;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering i->why = strdup(why);
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack i->who = strdup(who);
2fc09a9cdd1ad25bc7c53a23d5301eb952e1ce3dDaniel Mack
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering if (!i->why || !i->who) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = -ENOMEM;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto fail;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers fifo_fd = inhibitor_create_fifo(i);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers if (fifo_fd < 0) {
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers r = fifo_fd;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers goto fail;
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering reply = dbus_message_new_method_return(message);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!reply) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = -ENOMEM;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering goto fail;
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering }
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering if (!dbus_message_append_args(
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering reply,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering DBUS_TYPE_UNIX_FD, &fifo_fd,
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering DBUS_TYPE_INVALID)) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering r = -ENOMEM;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto fail;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering }
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering close_nointr_nofail(fifo_fd);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering *_reply = reply;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering inhibitor_start(i);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return 0;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poetteringfail:
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (i)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering inhibitor_free(i);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (fifo_fd >= 0)
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering close_nointr_nofail(fifo_fd);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (reply)
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering dbus_message_unref(reply);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r;
c51cf05646a11c65daf65c1123c77efb068f4f7bZbigniew Jędrzejewski-Szmek}
f9ac15442e4132f00eca5495d53c17062aae13e0Lennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poetteringstatic int trigger_device(Manager *m, struct udev_device *d) {
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct udev_enumerate *e;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering struct udev_list_entry *first, *item;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering int r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering assert(m);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering e = udev_enumerate_new(m->udev);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering if (!e) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = -ENOMEM;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
d2a623823f8d83c97c35fcd28f90e8cd59066f8aZbigniew Jędrzejewski-Szmek if (d) {
8086ffacdb1bfec5ec115d24626538bda6cc372eZbigniew Jędrzejewski-Szmek if (udev_enumerate_add_match_parent(e, d) < 0) {
8086ffacdb1bfec5ec115d24626538bda6cc372eZbigniew Jędrzejewski-Szmek r = -EIO;
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering goto finish;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (udev_enumerate_scan_devices(e) < 0) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = -EIO;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering goto finish;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering first = udev_enumerate_get_list_entry(e);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering udev_list_entry_foreach(item, first) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering char *t;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *p;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering p = udev_list_entry_get_name(item);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering t = strappend(p, "/uevent");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!t) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = -ENOMEM;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering goto finish;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering write_one_line_file(t, "change");
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering free(t);
9a5cb1371b6d8b0a04bd08665bcf9b06cb40c64cZbigniew Jędrzejewski-Szmek }
9a5cb1371b6d8b0a04bd08665bcf9b06cb40c64cZbigniew Jędrzejewski-Szmek
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = 0;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringfinish:
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (e)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt udev_enumerate_unref(e);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering return r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering}
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int attach_device(Manager *m, const char *seat, const char *sysfs) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering struct udev_device *d;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering char *rule = NULL, *file = NULL;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering const char *id_for_seat;
98b2f766b24c84fc49a4df954717b1f96bbce00dLennart Poettering int r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering assert(m);
cca1dfddd4ce4357113663532696488427cc54e4Lennart Poettering assert(seat);
59512f21d77d984cf1363fb0d1770218c5e17020Kay Sievers assert(sysfs);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering d = udev_device_new_from_syspath(m->udev, sysfs);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!d)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return -ENODEV;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!udev_device_has_tag(d, "seat")) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = -ENODEV;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering goto finish;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering if (!id_for_seat) {
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt r = -ENODEV;
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt goto finish;
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt }
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger r = -ENOMEM;
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger goto finish;
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger }
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger
eafe88e34a0698d2f4ebb747ab4911e35d0dfe4cTobias Hunger if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering r = -ENOMEM;
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering goto finish;
61331eab0a53cd9b8446eab6d1ebf1a046d8efc1Lennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering mkdir_p_label("/etc/udev/rules.d", 0755);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = write_one_line_file_atomic(file, rule);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (r < 0)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering goto finish;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering r = trigger_device(m, d);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringfinish:
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering free(rule);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering free(file);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (d)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering udev_device_unref(d);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering return r;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering}
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poetteringstatic int flush_devices(Manager *m) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering DIR *d;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
e48fdd84432bbf9c2ecc339183258c7c33116032Lennart Poettering assert(m);
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering
3db604b907323b8df0fc810216f6112056d26a02Lennart Poettering d = opendir("/etc/udev/rules.d");
b5884878a2874447b2a9f07f324a7cd909d96d48Lennart Poettering if (!d) {
b5884878a2874447b2a9f07f324a7cd909d96d48Lennart Poettering if (errno != ENOENT)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning("Failed to open /etc/udev/rules.d: %m");
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering } else {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering struct dirent *de;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering while ((de = readdir(d))) {
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!dirent_is_file(de))
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering continue;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!startswith(de->d_name, "72-seat-"))
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering continue;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (!endswith(de->d_name, ".rules"))
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering continue;
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering if (unlinkat(dirfd(d), de->d_name, 0) < 0)
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering log_warning("Failed to unlink %s: %m", de->d_name);
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering }
73b80ec2d999c45ce13f3e034704249d80829f7eLennart Poettering
1a14a53cfded6e78c6e8dfb73fdff0039971d642Lennart Poettering closedir(d);
}
return trigger_device(m, NULL);
}
static int have_multiple_sessions(
DBusConnection *connection,
Manager *m,
DBusMessage *message,
DBusError *error) {
Session *session;
Iterator i;
unsigned long ul;
assert(m);
ul = dbus_bus_get_unix_user(connection, dbus_message_get_sender(message), error);
if (ul == (unsigned long) -1)
return -EIO;
/* Check for other users' sessions. Greeter sessions do not count. */
HASHMAP_FOREACH(session, m->sessions, i)
if (session->class == SESSION_USER && session->user->uid != ul)
return true;
return false;
}
static int send_start_unit(DBusConnection *connection, const char *unit_name, DBusError *error) {
const char *mode = "replace";
assert(unit_name);
return bus_method_call_with_reply (
connection,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"StartUnit",
NULL,
NULL,
DBUS_TYPE_STRING, &unit_name,
DBUS_TYPE_STRING, &mode,
DBUS_TYPE_INVALID);
}
static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) {
static const char * const signal_name[_INHIBIT_WHAT_MAX] = {
[INHIBIT_SHUTDOWN] = "PrepareForShutdown",
[INHIBIT_SLEEP] = "PrepareForSleep"
};
dbus_bool_t active = _active;
DBusMessage *message;
int r = 0;
assert(m);
assert(w >= 0);
assert(w < _INHIBIT_WHAT_MAX);
assert(signal_name[w]);
message = dbus_message_new_signal("/org/freedesktop/login1", "org.freedesktop.login1.Manager", signal_name[w]);
if (!message)
return -ENOMEM;
if (!dbus_message_append_args(message, DBUS_TYPE_BOOLEAN, &active, DBUS_TYPE_INVALID) ||
!dbus_connection_send(m->bus, message, NULL))
r = -ENOMEM;
dbus_message_unref(message);
return r;
}
static int delay_shutdown_or_sleep(Manager *m, InhibitWhat w, const char *unit_name) {
assert(m);
assert(w >= 0);
assert(w < _INHIBIT_WHAT_MAX);
/* Tell everybody to prepare for shutdown/sleep */
send_prepare_for(m, w, true);
/* Update timestamp for timeout */
if (!m->delayed_unit)
m->delayed_timestamp = now(CLOCK_MONOTONIC);
/* Remember what we want to do, possibly overriding what kind
* of unit we previously queued. */
m->delayed_unit = unit_name;
m->delayed_what = w;
return 0;
}
static int bus_manager_can_shutdown_or_sleep(
Manager *m,
DBusConnection *connection,
DBusMessage *message,
InhibitWhat w,
const char *action,
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
const char *sleep_type,
DBusError *error,
DBusMessage **_reply) {
bool multiple_sessions, challenge, blocked, b;
const char *result;
DBusMessage *reply = NULL;
int r;
assert(m);
assert(connection);
assert(message);
assert(w >= 0);
assert(w <= _INHIBIT_WHAT_MAX);
assert(action);
assert(action_multiple_sessions);
assert(action_ignore_inhibit);
assert(error);
assert(_reply);
if (sleep_type) {
r = can_sleep(sleep_type);
if (r < 0)
return r;
if (r == 0) {
result = "na";
goto finish;
}
}
r = have_multiple_sessions(connection, m, message, error);
if (r < 0)
return r;
multiple_sessions = r > 0;
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL);
if (multiple_sessions) {
r = verify_polkit(connection, message, action_multiple_sessions, false, &challenge, error);
if (r < 0)
return r;
if (r > 0)
result = "yes";
else if (challenge)
result = "challenge";
else
result = "no";
}
if (blocked) {
r = verify_polkit(connection, message, action_ignore_inhibit, false, &challenge, error);
if (r < 0)
return r;
if (r > 0 && !result)
result = "yes";
else if (challenge && (!result || streq(result, "yes")))
result = "challenge";
else
result = "no";
}
if (!multiple_sessions && !blocked) {
/* If neither inhibit nor multiple sessions
* apply then just check the normal policy */
r = verify_polkit(connection, message, action, false, &challenge, error);
if (r < 0)
return r;
if (r > 0)
result = "yes";
else if (challenge)
result = "challenge";
else
result = "no";
}
finish:
reply = dbus_message_new_method_return(message);
if (!reply)
return -ENOMEM;
b = dbus_message_append_args(
reply,
DBUS_TYPE_STRING, &result,
DBUS_TYPE_INVALID);
if (!b) {
dbus_message_unref(reply);
return -ENOMEM;
}
*_reply = reply;
return 0;
}
int bus_manager_shutdown_or_sleep_now_or_later(
Manager *m,
const char *unit_name,
InhibitWhat w,
DBusError *error) {
bool delayed;
int r;
assert(m);
assert(unit_name);
assert(w >= 0);
assert(w <= _INHIBIT_WHAT_MAX);
delayed =
m->inhibit_delay_max > 0 &&
manager_is_inhibited(m, w, INHIBIT_DELAY, NULL);
if (delayed)
/* Shutdown is delayed, keep in mind what we
* want to do, and start a timeout */
r = delay_shutdown_or_sleep(m, w, unit_name);
else
/* Shutdown is not delayed, execute it
* immediately */
r = send_start_unit(m->bus, unit_name, error);
return r;
}
static int bus_manager_do_shutdown_or_sleep(
Manager *m,
DBusConnection *connection,
DBusMessage *message,
const char *unit_name,
InhibitWhat w,
const char *action,
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
const char *sleep_type,
DBusError *error,
DBusMessage **_reply) {
dbus_bool_t interactive;
bool multiple_sessions, blocked;
DBusMessage *reply = NULL;
int r;
assert(m);
assert(connection);
assert(message);
assert(unit_name);
assert(w >= 0);
assert(w <= _INHIBIT_WHAT_MAX);
assert(action);
assert(action_multiple_sessions);
assert(action_ignore_inhibit);
assert(error);
assert(_reply);
if (!dbus_message_get_args(
message,
error,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID))
return -EINVAL;
if (sleep_type) {
r = can_sleep(sleep_type);
if (r < 0)
return r;
if (r == 0)
return -ENOTSUP;
}
r = have_multiple_sessions(connection, m, message, error);
if (r < 0)
return r;
multiple_sessions = r > 0;
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL);
if (multiple_sessions) {
r = verify_polkit(connection, message, action_multiple_sessions, interactive, NULL, error);
if (r < 0)
return r;
}
if (blocked) {
r = verify_polkit(connection, message, action_ignore_inhibit, interactive, NULL, error);
if (r < 0)
return r;
}
if (!multiple_sessions && !blocked) {
r = verify_polkit(connection, message, action, interactive, NULL, error);
if (r < 0)
return r;
}
r = bus_manager_shutdown_or_sleep_now_or_later(m, unit_name, w, error);
if (r < 0)
return r;
reply = dbus_message_new_method_return(message);
if (!reply)
return -ENOMEM;
*_reply = reply;
return 0;
}
static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_handle_button, handle_button, HandleButton);
static const BusProperty bus_login_manager_properties[] = {
{ "ControlGroupHierarchy", bus_property_append_string, "s", offsetof(Manager, cgroup_path), true },
{ "Controllers", bus_property_append_strv, "as", offsetof(Manager, controllers), true },
{ "ResetControllers", bus_property_append_strv, "as", offsetof(Manager, reset_controllers), true },
{ "NAutoVTs", bus_property_append_unsigned, "u", offsetof(Manager, n_autovts) },
{ "KillOnlyUsers", bus_property_append_strv, "as", offsetof(Manager, kill_only_users), true },
{ "KillExcludeUsers", bus_property_append_strv, "as", offsetof(Manager, kill_exclude_users), true },
{ "KillUserProcesses", bus_property_append_bool, "b", offsetof(Manager, kill_user_processes) },
{ "IdleHint", bus_manager_append_idle_hint, "b", 0 },
{ "IdleSinceHint", bus_manager_append_idle_hint_since, "t", 0 },
{ "IdleSinceHintMonotonic", bus_manager_append_idle_hint_since, "t", 0 },
{ "BlockInhibited", bus_manager_append_inhibited, "s", 0 },
{ "DelayInhibited", bus_manager_append_inhibited, "s", 0 },
{ "InhibitDelayMaxUSec", bus_property_append_usec, "t", offsetof(Manager, inhibit_delay_max) },
{ "HandlePowerKey", bus_manager_append_handle_button, "s", offsetof(Manager, handle_power_key) },
{ "HandleSleepKey", bus_manager_append_handle_button, "s", offsetof(Manager, handle_sleep_key) },
{ "HandleLidSwitch", bus_manager_append_handle_button, "s", offsetof(Manager, handle_lid_switch) },
{ "PreparingForShutdown", bus_manager_append_preparing, "b", 0 },
{ "PreparingForSleep", bus_manager_append_preparing, "b", 0 },
{ NULL, }
};
static DBusHandlerResult manager_message_handler(
DBusConnection *connection,
DBusMessage *message,
void *userdata) {
Manager *m = userdata;
DBusError error;
DBusMessage *reply = NULL;
int r;
assert(connection);
assert(message);
assert(m);
dbus_error_init(&error);
if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSession")) {
const char *name;
char *p;
Session *session;
bool b;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
session = hashmap_get(m->sessions, name);
if (!session)
return bus_send_error_reply(connection, message, &error, -ENOENT);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
p = session_bus_path(session);
if (!p)
goto oom;
b = dbus_message_append_args(
reply,
DBUS_TYPE_OBJECT_PATH, &p,
DBUS_TYPE_INVALID);
free(p);
if (!b)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSessionByPID")) {
uint32_t pid;
char *p;
Session *session;
bool b;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_UINT32, &pid,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
r = manager_get_session_by_pid(m, pid, &session);
if (r <= 0)
return bus_send_error_reply(connection, message, NULL, r < 0 ? r : -ENOENT);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
p = session_bus_path(session);
if (!p)
goto oom;
b = dbus_message_append_args(
reply,
DBUS_TYPE_OBJECT_PATH, &p,
DBUS_TYPE_INVALID);
free(p);
if (!b)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetUser")) {
uint32_t uid;
char *p;
User *user;
bool b;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_UINT32, &uid,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
if (!user)
return bus_send_error_reply(connection, message, &error, -ENOENT);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
p = user_bus_path(user);
if (!p)
goto oom;
b = dbus_message_append_args(
reply,
DBUS_TYPE_OBJECT_PATH, &p,
DBUS_TYPE_INVALID);
free(p);
if (!b)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "GetSeat")) {
const char *name;
char *p;
Seat *seat;
bool b;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
seat = hashmap_get(m->seats, name);
if (!seat)
return bus_send_error_reply(connection, message, &error, -ENOENT);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
p = seat_bus_path(seat);
if (!p)
goto oom;
b = dbus_message_append_args(
reply,
DBUS_TYPE_OBJECT_PATH, &p,
DBUS_TYPE_INVALID);
free(p);
if (!b)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSessions")) {
char *p;
Session *session;
Iterator i;
DBusMessageIter iter, sub;
const char *empty = "";
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
dbus_message_iter_init_append(reply, &iter);
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(susso)", &sub))
goto oom;
HASHMAP_FOREACH(session, m->sessions, i) {
DBusMessageIter sub2;
uint32_t uid;
if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
goto oom;
uid = session->user->uid;
p = session_bus_path(session);
if (!p)
goto oom;
if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->id) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &session->user->name) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, session->seat ? (const char**) &session->seat->id : &empty) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) {
free(p);
goto oom;
}
free(p);
if (!dbus_message_iter_close_container(&sub, &sub2))
goto oom;
}
if (!dbus_message_iter_close_container(&iter, &sub))
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListUsers")) {
char *p;
User *user;
Iterator i;
DBusMessageIter iter, sub;
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
dbus_message_iter_init_append(reply, &iter);
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(uso)", &sub))
goto oom;
HASHMAP_FOREACH(user, m->users, i) {
DBusMessageIter sub2;
uint32_t uid;
if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
goto oom;
uid = user->uid;
p = user_bus_path(user);
if (!p)
goto oom;
if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &user->name) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) {
free(p);
goto oom;
}
free(p);
if (!dbus_message_iter_close_container(&sub, &sub2))
goto oom;
}
if (!dbus_message_iter_close_container(&iter, &sub))
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListSeats")) {
char *p;
Seat *seat;
Iterator i;
DBusMessageIter iter, sub;
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
dbus_message_iter_init_append(reply, &iter);
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(so)", &sub))
goto oom;
HASHMAP_FOREACH(seat, m->seats, i) {
DBusMessageIter sub2;
if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
goto oom;
p = seat_bus_path(seat);
if (!p)
goto oom;
if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &seat->id) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &p)) {
free(p);
goto oom;
}
free(p);
if (!dbus_message_iter_close_container(&sub, &sub2))
goto oom;
}
if (!dbus_message_iter_close_container(&iter, &sub))
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ListInhibitors")) {
Inhibitor *inhibitor;
Iterator i;
DBusMessageIter iter, sub;
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
dbus_message_iter_init_append(reply, &iter);
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssssuu)", &sub))
goto oom;
HASHMAP_FOREACH(inhibitor, m->inhibitors, i) {
DBusMessageIter sub2;
dbus_uint32_t uid, pid;
const char *what, *who, *why, *mode;
if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2))
goto oom;
what = strempty(inhibit_what_to_string(inhibitor->what));
who = strempty(inhibitor->who);
why = strempty(inhibitor->why);
mode = strempty(inhibit_mode_to_string(inhibitor->mode));
uid = (dbus_uint32_t) inhibitor->uid;
pid = (dbus_uint32_t) inhibitor->pid;
if (!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &what) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &who) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &why) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &mode) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &uid) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &pid))
goto oom;
if (!dbus_message_iter_close_container(&sub, &sub2))
goto oom;
}
if (!dbus_message_iter_close_container(&iter, &sub))
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Inhibit")) {
r = bus_manager_inhibit(m, connection, message, &error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CreateSession")) {
r = bus_manager_create_session(m, message, &reply);
/* Don't delay the work on OOM here, since it might be
* triggered by a low RLIMIT_NOFILE here (since we
* send a dupped fd to the client), and we'd rather
* see this fail quickly then be retried later */
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ReleaseSession")) {
const char *name;
Session *session;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
session = hashmap_get(m->sessions, name);
if (!session)
return bus_send_error_reply(connection, message, &error, -ENOENT);
/* We use the FIFO to detect stray sessions where the
process invoking PAM dies abnormally. We need to make
sure that that process is not killed if at the clean
end of the session it closes the FIFO. Hence, with
this call explicitly turn off the FIFO logic, so that
the PAM code can finish clean up on its own */
session_remove_fifo(session);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSession")) {
const char *name;
Session *session;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
session = hashmap_get(m->sessions, name);
if (!session)
return bus_send_error_reply(connection, message, &error, -ENOENT);
r = session_activate(session);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "ActivateSessionOnSeat")) {
const char *session_name, *seat_name;
Session *session;
Seat *seat;
/* Same as ActivateSession() but refuses to work if
* the seat doesn't match */
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &session_name,
DBUS_TYPE_STRING, &seat_name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
session = hashmap_get(m->sessions, session_name);
if (!session)
return bus_send_error_reply(connection, message, &error, -ENOENT);
seat = hashmap_get(m->seats, seat_name);
if (!seat)
return bus_send_error_reply(connection, message, &error, -ENOENT);
if (session->seat != seat)
return bus_send_error_reply(connection, message, &error, -EINVAL);
r = session_activate(session);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSession") ||
dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "UnlockSession")) {
const char *name;
Session *session;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
session = hashmap_get(m->sessions, name);
if (!session)
return bus_send_error_reply(connection, message, &error, -ENOENT);
if (session_send_lock(session, streq(dbus_message_get_member(message), "LockSession")) < 0)
goto oom;
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "LockSessions")) {
Session *session;
Iterator i;
HASHMAP_FOREACH(session, m->sessions, i)
if (session_send_lock(session, true) < 0)
goto oom;
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillSession")) {
const char *swho;
int32_t signo;
KillWho who;
const char *name;
Session *session;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &swho,
DBUS_TYPE_INT32, &signo,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
if (isempty(swho))
who = KILL_ALL;
else {
who = kill_who_from_string(swho);
if (who < 0)
return bus_send_error_reply(connection, message, &error, -EINVAL);
}
if (signo <= 0 || signo >= _NSIG)
return bus_send_error_reply(connection, message, &error, -EINVAL);
session = hashmap_get(m->sessions, name);
if (!session)
return bus_send_error_reply(connection, message, &error, -ENOENT);
r = session_kill(session, who, signo);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "KillUser")) {
uint32_t uid;
User *user;
int32_t signo;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_UINT32, &uid,
DBUS_TYPE_INT32, &signo,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
if (signo <= 0 || signo >= _NSIG)
return bus_send_error_reply(connection, message, &error, -EINVAL);
user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
if (!user)
return bus_send_error_reply(connection, message, &error, -ENOENT);
r = user_kill(user, signo);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSession")) {
const char *name;
Session *session;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
session = hashmap_get(m->sessions, name);
if (!session)
return bus_send_error_reply(connection, message, &error, -ENOENT);
r = session_stop(session);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateUser")) {
uint32_t uid;
User *user;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_UINT32, &uid,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
user = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
if (!user)
return bus_send_error_reply(connection, message, &error, -ENOENT);
r = user_stop(user);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "TerminateSeat")) {
const char *name;
Seat *seat;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
seat = hashmap_get(m->seats, name);
if (!seat)
return bus_send_error_reply(connection, message, &error, -ENOENT);
r = seat_stop_sessions(seat);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, r);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "SetUserLinger")) {
uint32_t uid;
struct passwd *pw;
dbus_bool_t b, interactive;
char *path;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_UINT32, &uid,
DBUS_TYPE_BOOLEAN, &b,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
errno = 0;
pw = getpwuid(uid);
if (!pw)
return bus_send_error_reply(connection, message, NULL, errno ? -errno : -EINVAL);
r = verify_polkit(connection, message, "org.freedesktop.login1.set-user-linger", interactive, NULL, &error);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
mkdir_p_label("/var/lib/systemd", 0755);
r = mkdir_safe_label("/var/lib/systemd/linger", 0755, 0, 0);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
path = strappend("/var/lib/systemd/linger/", pw->pw_name);
if (!path)
goto oom;
if (b) {
User *u;
r = touch(path);
free(path);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
if (manager_add_user_by_uid(m, uid, &u) >= 0)
user_start(u);
} else {
User *u;
r = unlink(path);
free(path);
if (r < 0 && errno != ENOENT)
return bus_send_error_reply(connection, message, &error, -errno);
u = hashmap_get(m->users, ULONG_TO_PTR((unsigned long) uid));
if (u)
user_add_to_gc_queue(u);
}
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "AttachDevice")) {
const char *sysfs, *seat;
dbus_bool_t interactive;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_STRING, &seat,
DBUS_TYPE_STRING, &sysfs,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
if (!path_startswith(sysfs, "/sys") || !seat_name_is_valid(seat))
return bus_send_error_reply(connection, message, NULL, -EINVAL);
r = verify_polkit(connection, message, "org.freedesktop.login1.attach-device", interactive, NULL, &error);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
r = attach_device(m, seat, sysfs);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, -EINVAL);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "FlushDevices")) {
dbus_bool_t interactive;
if (!dbus_message_get_args(
message,
&error,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID))
return bus_send_error_reply(connection, message, &error, -EINVAL);
r = verify_polkit(connection, message, "org.freedesktop.login1.flush-devices", interactive, NULL, &error);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
r = flush_devices(m);
if (r < 0)
return bus_send_error_reply(connection, message, NULL, -EINVAL);
reply = dbus_message_new_method_return(message);
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "PowerOff")) {
r = bus_manager_do_shutdown_or_sleep(
m, connection, message,
SPECIAL_POWEROFF_TARGET,
INHIBIT_SHUTDOWN,
"org.freedesktop.login1.power-off",
"org.freedesktop.login1.power-off-multiple-sessions",
"org.freedesktop.login1.power-off-ignore-inhibit",
NULL,
&error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Reboot")) {
r = bus_manager_do_shutdown_or_sleep(
m, connection, message,
SPECIAL_REBOOT_TARGET,
INHIBIT_SHUTDOWN,
"org.freedesktop.login1.reboot",
"org.freedesktop.login1.reboot-multiple-sessions",
"org.freedesktop.login1.reboot-ignore-inhibit",
NULL,
&error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Suspend")) {
r = bus_manager_do_shutdown_or_sleep(
m, connection, message,
SPECIAL_SUSPEND_TARGET,
INHIBIT_SLEEP,
"org.freedesktop.login1.suspend",
"org.freedesktop.login1.suspend-multiple-sessions",
"org.freedesktop.login1.suspend-ignore-inhibit",
"mem",
&error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "Hibernate")) {
r = bus_manager_do_shutdown_or_sleep(
m, connection, message,
SPECIAL_HIBERNATE_TARGET,
INHIBIT_SLEEP,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"disk",
&error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanPowerOff")) {
r = bus_manager_can_shutdown_or_sleep(
m, connection, message,
INHIBIT_SHUTDOWN,
"org.freedesktop.login1.power-off",
"org.freedesktop.login1.power-off-multiple-sessions",
"org.freedesktop.login1.power-off-ignore-inhibit",
NULL,
&error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanReboot")) {
r = bus_manager_can_shutdown_or_sleep(
m, connection, message,
INHIBIT_SHUTDOWN,
"org.freedesktop.login1.reboot",
"org.freedesktop.login1.reboot-multiple-sessions",
"org.freedesktop.login1.reboot-ignore-inhibit",
NULL,
&error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanSuspend")) {
r = bus_manager_can_shutdown_or_sleep(
m, connection, message,
INHIBIT_SLEEP,
"org.freedesktop.login1.suspend",
"org.freedesktop.login1.suspend-multiple-sessions",
"org.freedesktop.login1.suspend-ignore-inhibit",
"mem",
&error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Manager", "CanHibernate")) {
r = bus_manager_can_shutdown_or_sleep(
m, connection, message,
INHIBIT_SLEEP,
"org.freedesktop.login1.hibernate",
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"disk",
&error, &reply);
if (r < 0)
return bus_send_error_reply(connection, message, &error, r);
} else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
char *introspection = NULL;
FILE *f;
Iterator i;
Session *session;
Seat *seat;
User *user;
size_t size;
char *p;
if (!(reply = dbus_message_new_method_return(message)))
goto oom;
/* We roll our own introspection code here, instead of
* relying on bus_default_message_handler() because we
* need to generate our introspection string
* dynamically. */
if (!(f = open_memstream(&introspection, &size)))
goto oom;
fputs(INTROSPECTION_BEGIN, f);
HASHMAP_FOREACH(seat, m->seats, i) {
p = bus_path_escape(seat->id);
if (p) {
fprintf(f, "<node name=\"seat/%s\"/>", p);
free(p);
}
}
HASHMAP_FOREACH(user, m->users, i)
fprintf(f, "<node name=\"user/%llu\"/>", (unsigned long long) user->uid);
HASHMAP_FOREACH(session, m->sessions, i) {
p = bus_path_escape(session->id);
if (p) {
fprintf(f, "<node name=\"session/%s\"/>", p);
free(p);
}
}
fputs(INTROSPECTION_END, f);
if (ferror(f)) {
fclose(f);
free(introspection);
goto oom;
}
fclose(f);
if (!introspection)
goto oom;
if (!dbus_message_append_args(reply, DBUS_TYPE_STRING, &introspection, DBUS_TYPE_INVALID)) {
free(introspection);
goto oom;
}
free(introspection);
} else {
const BusBoundProperties bps[] = {
{ "org.freedesktop.login1.Manager", bus_login_manager_properties, m },
{ NULL, }
};
return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, bps);
}
if (reply) {
if (!dbus_connection_send(connection, reply, NULL))
goto oom;
dbus_message_unref(reply);
}
return DBUS_HANDLER_RESULT_HANDLED;
oom:
if (reply)
dbus_message_unref(reply);
dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
const DBusObjectPathVTable bus_manager_vtable = {
.message_function = manager_message_handler
};
DBusHandlerResult bus_message_filter(
DBusConnection *connection,
DBusMessage *message,
void *userdata) {
Manager *m = userdata;
DBusError error;
assert(m);
assert(connection);
assert(message);
dbus_error_init(&error);
if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
const char *cgroup;
if (!dbus_message_get_args(message, &error,
DBUS_TYPE_STRING, &cgroup,
DBUS_TYPE_INVALID))
log_error("Failed to parse Released message: %s", bus_error_message(&error));
else
manager_cgroup_notify_empty(m, cgroup);
}
dbus_error_free(&error);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
int manager_send_changed(Manager *manager, const char *properties) {
DBusMessage *m;
int r = -ENOMEM;
assert(manager);
m = bus_properties_changed_new("/org/freedesktop/login1", "org.freedesktop.login1.Manager", properties);
if (!m)
goto finish;
if (!dbus_connection_send(manager->bus, m, NULL))
goto finish;
r = 0;
finish:
if (m)
dbus_message_unref(m);
return r;
}
int manager_dispatch_delayed(Manager *manager) {
const char *unit_name;
DBusError error;
bool delayed;
int r;
assert(manager);
if (!manager->delayed_unit)
return 0;
/* Continue delay? */
delayed =
manager->delayed_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC) &&
manager_is_inhibited(manager, manager->delayed_what, INHIBIT_DELAY, NULL);
if (delayed)
return 0;
/* Reset delay data */
unit_name = manager->delayed_unit;
manager->delayed_unit = NULL;
/* Actually do the shutdown */
dbus_error_init(&error);
r = send_start_unit(manager->bus, unit_name, &error);
if (r < 0) {
log_warning("Failed to send delayed message: %s", bus_error_message_or_strerror(&error, -r));
dbus_error_free(&error);
return r;
}
/* Tell people about it */
send_prepare_for(manager, manager->delayed_what, false);
return 1;
}