summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/loginctl.c323
-rw-r--r--src/logind-dbus.c29
-rw-r--r--src/logind-session-dbus.c37
-rw-r--r--src/logind-session.h1
-rw-r--r--src/sysfs-show.c28
5 files changed, 386 insertions, 32 deletions
diff --git a/src/loginctl.c b/src/loginctl.c
index 23c998cba2..bb5be908f6 100644
--- a/src/loginctl.c
+++ b/src/loginctl.c
@@ -527,14 +527,13 @@ static void print_seat_status_info(SeatStatusInfo *i) {
unsigned c;
c = columns();
- if (c > 18)
- c -= 18;
+ if (c > 21)
+ c -= 21;
else
c = 0;
printf("\t Devices:\n");
-
show_sysfs(i->id, "\t\t ", c);
}
}
@@ -1166,7 +1165,10 @@ static int activate(DBusConnection *bus, char **args, unsigned n) {
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
- "ActivateSession");
+ streq(args[0], "lock-session") ? "LockSession" :
+ streq(args[0], "unlock-session") ? "UnlockSession" :
+ streq(args[0], "terminate-session") ? "TerminateSession" :
+ "ActivateSession");
if (!m) {
log_error("Could not allocate message.");
ret = -ENOMEM;
@@ -1210,19 +1212,312 @@ static int kill_session(DBusConnection *bus, char **args, unsigned n) {
}
static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
- return 0;
+ DBusMessage *m = NULL, *reply = NULL;
+ int ret = 0;
+ DBusError error;
+ unsigned i;
+ dbus_bool_t b, interactive = true;
+
+ assert(bus);
+ assert(args);
+
+ dbus_error_init(&error);
+
+ b = streq(args[0], "enable-linger");
+
+ for (i = 1; i < n; i++) {
+ uint32_t uid;
+
+ m = dbus_message_new_method_call(
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "SetUserLinger");
+ if (!m) {
+ log_error("Could not allocate message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ if (safe_atou32(args[i], &uid) < 0) {
+ struct passwd *pw;
+
+ errno = 0;
+ pw = getpwnam(args[i]);
+ if (!pw) {
+ ret = errno ? -errno : -ENOENT;
+ log_error("Failed to resolve user %s: %s", args[i], strerror(-ret));
+ goto finish;
+ }
+
+ uid = pw->pw_uid;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_UINT32, &uid,
+ DBUS_TYPE_BOOLEAN, &b,
+ DBUS_TYPE_BOOLEAN, &interactive,
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ ret = -EIO;
+ goto finish;
+ }
+
+ dbus_message_unref(m);
+ dbus_message_unref(reply);
+ m = reply = NULL;
+ }
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return ret;
+}
+
+static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
+ DBusMessage *m = NULL, *reply = NULL;
+ int ret = 0;
+ DBusError error;
+ unsigned i;
+
+ assert(bus);
+ assert(args);
+
+ dbus_error_init(&error);
+
+ for (i = 1; i < n; i++) {
+ uint32_t u;
+
+ m = dbus_message_new_method_call(
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "TerminateUser");
+ if (!m) {
+ log_error("Could not allocate message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ if (safe_atou32(args[i], &u) < 0) {
+ struct passwd *pw;
+
+ errno = 0;
+ pw = getpwnam(args[i]);
+ if (!pw) {
+ ret = errno ? -errno : -ENOENT;
+ log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
+ goto finish;
+ }
+
+ u = pw->pw_uid;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_UINT32, &u,
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ ret = -EIO;
+ goto finish;
+ }
+
+ dbus_message_unref(m);
+ dbus_message_unref(reply);
+ m = reply = NULL;
+ }
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return ret;
}
static int attach(DBusConnection *bus, char **args, unsigned n) {
- return 0;
+ DBusMessage *m = NULL, *reply = NULL;
+ int ret = 0;
+ DBusError error;
+ unsigned i;
+ dbus_bool_t interactive = true;
+
+ assert(bus);
+ assert(args);
+
+ dbus_error_init(&error);
+
+ for (i = 2; i < n; i++) {
+ m = dbus_message_new_method_call(
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "AttachDevice");
+ if (!m) {
+ log_error("Could not allocate message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_STRING, &args[1],
+ DBUS_TYPE_STRING, &args[i],
+ DBUS_TYPE_BOOLEAN, &interactive,
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ ret = -EIO;
+ goto finish;
+ }
+
+ dbus_message_unref(m);
+ dbus_message_unref(reply);
+ m = reply = NULL;
+ }
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return ret;
}
static int flush_devices(DBusConnection *bus, char **args, unsigned n) {
- return 0;
+ DBusMessage *m = NULL, *reply = NULL;
+ int ret = 0;
+ DBusError error;
+ dbus_bool_t interactive = true;
+
+ assert(bus);
+ assert(args);
+
+ dbus_error_init(&error);
+
+ m = dbus_message_new_method_call(
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "FlushDevices");
+ if (!m) {
+ log_error("Could not allocate message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_BOOLEAN, &interactive,
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ ret = -EIO;
+ goto finish;
+ }
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return ret;
}
static int terminate_seat(DBusConnection *bus, char **args, unsigned n) {
- return 0;
+ DBusMessage *m = NULL, *reply = NULL;
+ int ret = 0;
+ DBusError error;
+ unsigned i;
+
+ assert(bus);
+ assert(args);
+
+ dbus_error_init(&error);
+
+ for (i = 1; i < n; i++) {
+ m = dbus_message_new_method_call(
+ "org.freedesktop.login1",
+ "/org/freedesktop/login1",
+ "org.freedesktop.login1.Manager",
+ "TerminateSeat");
+ if (!m) {
+ log_error("Could not allocate message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ if (!dbus_message_append_args(m,
+ DBUS_TYPE_STRING, &args[i],
+ DBUS_TYPE_INVALID)) {
+ log_error("Could not append arguments to message.");
+ ret = -ENOMEM;
+ goto finish;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
+ if (!reply) {
+ log_error("Failed to issue method call: %s", bus_error_message(&error));
+ ret = -EIO;
+ goto finish;
+ }
+
+ dbus_message_unref(m);
+ dbus_message_unref(reply);
+ m = reply = NULL;
+ }
+
+finish:
+ if (m)
+ dbus_message_unref(m);
+
+ if (reply)
+ dbus_message_unref(reply);
+
+ dbus_error_free(&error);
+
+ return ret;
}
static int help(void) {
@@ -1245,6 +1540,7 @@ static int help(void) {
" show-session [ID...] Show property of one or more sessions\n"
" activate [ID] Activate a session\n"
" lock-session [ID...] Screen lock one or more sessions\n"
+ " unlock-session [ID...] Screen unlock one or more sessions\n"
" terminate-session [ID...] Terminate one or more sessions\n"
" kill-session [ID...] Send signal to processes of a session\n"
" list-users List users\n"
@@ -1381,22 +1677,23 @@ static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError
{ "show-session", MORE, 1, show },
{ "activate", EQUAL, 2, activate },
{ "lock-session", MORE, 2, activate },
+ { "unlock-session", MORE, 2, activate },
{ "terminate-session", MORE, 2, activate },
- { "kill-session", MORE, 2, kill_session },
+ { "kill-session", MORE, 2, kill_session }, /* missing */
{ "list-users", EQUAL, 1, list_users },
{ "user-status", MORE, 2, show },
{ "show-user", MORE, 1, show },
{ "enable-linger", MORE, 2, enable_linger },
{ "disable-linger", MORE, 2, enable_linger },
- { "terminate-user", MORE, 2, enable_linger },
- { "kill-user", MORE, 2, kill_session },
+ { "terminate-user", MORE, 2, terminate_user },
+ { "kill-user", MORE, 2, kill_session }, /* missing */
{ "list-seats", EQUAL, 1, list_seats },
{ "seat-status", MORE, 2, show },
{ "show-seat", MORE, 1, show },
{ "attach", MORE, 3, attach },
{ "flush-devices", EQUAL, 1, flush_devices },
- { "terminate-seat", MORE, 2, terminate_seat },
- { "kill-seat", MORE, 2, kill_session },
+ { "terminate-seat", MORE, 2, terminate_seat }, /* missing */
+ { "kill-seat", MORE, 2, kill_session }, /* missing */
};
int left;
diff --git a/src/logind-dbus.c b/src/logind-dbus.c
index a2a442ee27..ec39d56d9e 100644
--- a/src/logind-dbus.c
+++ b/src/logind-dbus.c
@@ -75,6 +75,12 @@
" <method name=\"ActivateSession\">\n" \
" <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
" </method>\n" \
+ " <method name=\"LockSession\">\n" \
+ " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
+ " </method>\n" \
+ " <method name=\"UnlockSession\">\n" \
+ " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
+ " </method>\n" \
" <method name=\"TerminateSession\">\n" \
" <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
" </method>\n" \
@@ -980,6 +986,29 @@ static DBusHandlerResult manager_message_handler(
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", "TerminateSession")) {
const char *name;
Session *session;
diff --git a/src/logind-session-dbus.c b/src/logind-session-dbus.c
index eca33e5e24..5fe391cca4 100644
--- a/src/logind-session-dbus.c
+++ b/src/logind-session-dbus.c
@@ -283,17 +283,8 @@ static DBusHandlerResult session_message_dispatch(
} else if (dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Lock") ||
dbus_message_is_method_call(message, "org.freedesktop.login1.Session", "Unlock")) {
- bool b;
- DBusMessage *sig;
- sig = dbus_message_new_signal(dbus_message_get_path(message), "org.freedesktop.login1.Session", dbus_message_get_member(message));
- if (!sig)
- goto oom;
-
- b = dbus_connection_send(connection, sig, NULL);
- dbus_message_unref(sig);
-
- if (!b)
+ if (session_send_signal(s, streq(dbus_message_get_member(message), "Lock")) < 0)
goto oom;
reply = dbus_message_new_method_return(message);
@@ -460,3 +451,29 @@ finish:
return r;
}
+
+int session_send_lock(Session *s, bool lock) {
+ DBusMessage *m;
+ bool b;
+ char *p;
+
+ assert(s);
+
+ p = session_bus_path(s);
+ if (!p)
+ return -ENOMEM;
+
+ m = dbus_message_new_signal(p, "org.freedesktop.login1.Session", lock ? "Lock" : "Unlock");
+ free(p);
+
+ if (!m)
+ return -ENOMEM;
+
+ b = dbus_connection_send(s->manager->bus, m, NULL);
+ dbus_message_unref(m);
+
+ if (!b)
+ return -ENOMEM;
+
+ return 0;
+}
diff --git a/src/logind-session.h b/src/logind-session.h
index e58ff6fd8f..d9f44ef0e0 100644
--- a/src/logind-session.h
+++ b/src/logind-session.h
@@ -105,6 +105,7 @@ extern const DBusObjectPathVTable bus_session_vtable;
int session_send_signal(Session *s, bool new_session);
int session_send_changed(Session *s, const char *properties);
+int session_send_lock(Session *s, bool lock);
const char* session_type_to_string(SessionType t);
SessionType session_type_from_string(const char *s);
diff --git a/src/sysfs-show.c b/src/sysfs-show.c
index d12d3ccfc9..b456bf1271 100644
--- a/src/sysfs-show.c
+++ b/src/sysfs-show.c
@@ -59,7 +59,8 @@ static int show_sysfs_one(
while (*item) {
struct udev_list_entry *next, *lookahead;
struct udev_device *d;
- const char *sn, *id, *name, *sysfs, *subsystem, *sysname;
+ const char *sn, *name, *sysfs, *subsystem, *sysname;
+ char *l, *k;
sysfs = udev_list_entry_get_name(*item);
if (!path_startswith(sysfs, sub))
@@ -82,7 +83,6 @@ static int show_sysfs_one(
continue;
}
- id = udev_device_get_property_value(d, "ID_FOR_SEAT");
name = udev_device_get_sysattr_value(d, "name");
if (!name)
name = udev_device_get_sysattr_value(d, "id");
@@ -109,7 +109,7 @@ static int show_sysfs_one(
if (isempty(lookahead_sn))
lookahead_sn = "seat0";
- found = streq(seat, lookahead_sn) && device_has_tag(d, "seat");
+ found = streq(seat, lookahead_sn) && device_has_tag(lookahead_d, "seat");
udev_device_unref(lookahead_d);
if (found)
@@ -120,19 +120,29 @@ static int show_sysfs_one(
lookahead = udev_list_entry_get_next(lookahead);
}
- printf("%s%s %s (%s:%s)", prefix, lookahead ? "\342\224\234" : "\342\224\224", id ? id : sysfs, subsystem, sysname);
+ k = ellipsize(sysfs, n_columns, 20);
+ printf("%s%s %s\n", prefix, lookahead ? "\342\224\234" : "\342\224\224", k ? k : sysfs);
+ free(k);
- if (name)
- printf(" \"%s\"\n", name);
- else
- printf("\n");
+ if (asprintf(&l,
+ "(%s:%s)%s%s%s",
+ subsystem, sysname,
+ name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) {
+ udev_device_unref(d);
+ return -ENOMEM;
+ }
+
+ k = ellipsize(l, n_columns, 70);
+ printf("%s%s %s\n", prefix, lookahead ? "\342\224\202" : " ", k ? k : l);
+ free(k);
+ free(l);
*item = next;
if (*item) {
char *p;
p = strappend(prefix, lookahead ? "\342\224\202 " : " ");
- show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
+ show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2);
free(p);
}