X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogin%2Floginctl.c;h=24941fef34c0945b4ef1e777ee5435286ff9bcdd;hp=7e0056c589d68ba6273491d4dc4553083505ef48;hb=8481248b9fbddc6d5e6ff26eb23505ef13dc85f7;hpb=1e5678d023ab57807d3de08e10304e36bf9a1950 diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 7e0056c58..24941fef3 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -6,16 +6,16 @@ Copyright 2010 Lennart Poettering systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. systemd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see . ***/ @@ -35,6 +35,7 @@ #include "strv.h" #include "cgroup-show.h" #include "sysfs-show.h" +#include "spawn-polkit-agent.h" static char **arg_property = NULL; static bool arg_all = false; @@ -46,61 +47,47 @@ static enum transport { TRANSPORT_SSH, TRANSPORT_POLKIT } arg_transport = TRANSPORT_NORMAL; +static bool arg_ask_password = true; static const char *arg_host = NULL; -static bool on_tty(void) { - static int t = -1; - - /* Note that this is invoked relatively early, before we start - * the pager. That means the value we return reflects whether - * we originally were started on a tty, not if we currently - * are. But this is intended, since we want colour and so on - * when run in our own pager. */ +static void pager_open_if_enabled(void) { - if (_unlikely_(t < 0)) - t = isatty(STDOUT_FILENO) > 0; + /* Cache result before we open the pager */ + if (arg_no_pager) + return; - return t; + pager_open(); } -static void pager_open_if_enabled(void) { +static void polkit_agent_open_if_enabled(void) { - /* Cache result before we open the pager */ - on_tty(); + /* Open the polkit agent as a child process if necessary */ - if (!arg_no_pager) - pager_open(); + if (!arg_ask_password) + return; + + polkit_agent_open(); } static int list_sessions(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL, *reply = NULL; - DBusError error; + DBusMessage *reply = NULL; int r; DBusMessageIter iter, sub, sub2; unsigned k = 0; - dbus_error_init(&error); - - assert(bus); - pager_open_if_enabled(); - m = dbus_message_new_method_call( + r = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", - "ListSessions"); - if (!m) { - log_error("Could not allocate message."); - return -ENOMEM; - } - - 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)); - r = -EIO; + "ListSessions", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) goto finish; - } if (!dbus_message_iter_init(reply, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || @@ -150,46 +137,31 @@ static int list_sessions(DBusConnection *bus, char **args, unsigned n) { r = 0; finish: - if (m) - dbus_message_unref(m); - if (reply) dbus_message_unref(reply); - dbus_error_free(&error); - return r; } static int list_users(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL, *reply = NULL; - DBusError error; + DBusMessage *reply = NULL; int r; DBusMessageIter iter, sub, sub2; unsigned k = 0; - dbus_error_init(&error); - - assert(bus); - pager_open_if_enabled(); - m = dbus_message_new_method_call( + r = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", - "ListUsers"); - if (!m) { - log_error("Could not allocate message."); - return -ENOMEM; - } - - 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)); - r = -EIO; - goto finish; - } + "ListUsers", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) + goto finish; if (!dbus_message_iter_init(reply, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || @@ -237,46 +209,31 @@ static int list_users(DBusConnection *bus, char **args, unsigned n) { r = 0; finish: - if (m) - dbus_message_unref(m); - if (reply) dbus_message_unref(reply); - dbus_error_free(&error); - return r; } static int list_seats(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL, *reply = NULL; - DBusError error; + DBusMessage *reply = NULL; int r; DBusMessageIter iter, sub, sub2; unsigned k = 0; - dbus_error_init(&error); - - assert(bus); - pager_open_if_enabled(); - m = dbus_message_new_method_call( + r = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", - "ListSeats"); - if (!m) { - log_error("Could not allocate message."); - return -ENOMEM; - } - - 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)); - r = -EIO; + "ListSeats", + &reply, + NULL, + DBUS_TYPE_INVALID); + if (r) goto finish; - } if (!dbus_message_iter_init(reply, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || @@ -322,14 +279,9 @@ static int list_seats(DBusConnection *bus, char **args, unsigned n) { r = 0; finish: - if (m) - dbus_message_unref(m); - if (reply) dbus_message_unref(reply); - dbus_error_free(&error); - return r; } @@ -338,7 +290,7 @@ typedef struct SessionStatusInfo { uid_t uid; const char *name; usec_t timestamp; - const char *control_group; + const char *default_control_group; int vtnr; const char *seat; const char *tty; @@ -349,14 +301,15 @@ typedef struct SessionStatusInfo { const char *service; pid_t leader; const char *type; - bool active; + const char *class; + const char *state; } SessionStatusInfo; typedef struct UserStatusInfo { uid_t uid; const char *name; usec_t timestamp; - const char *control_group; + const char *default_control_group; const char *state; char **sessions; const char *display; @@ -431,16 +384,25 @@ static void print_session_status_info(SessionStatusInfo *i) { if (i->type) printf("; type %s", i->type); + if (i->class) + printf("; class %s", i->class); + printf("\n"); - } else if (i->type) + } else if (i->type) { printf("\t Type: %s\n", i->type); - printf("\t Active: %s\n", yes_no(i->active)); + if (i->class) + printf("; class %s", i->class); + } else if (i->class) + printf("\t Class: %s\n", i->class); + + if (i->state) + printf("\t State: %s\n", i->state); - if (i->control_group) { + if (i->default_control_group) { unsigned c; - printf("\t CGroup: %s\n", i->control_group); + printf("\t CGroup: %s\n", i->default_control_group); if (arg_transport != TRANSPORT_SSH) { c = columns(); @@ -449,7 +411,7 @@ static void print_session_status_info(SessionStatusInfo *i) { else c = 0; - show_cgroup_by_path(i->control_group, "\t\t ", c, false); + show_cgroup_and_extra_by_spec(i->default_control_group, "\t\t ", c, false, arg_all, &i->leader, i->leader > 0 ? 1 : 0); } } } @@ -489,10 +451,10 @@ static void print_user_status_info(UserStatusInfo *i) { printf("\n"); } - if (i->control_group) { + if (i->default_control_group) { unsigned c; - printf("\t CGroup: %s\n", i->control_group); + printf("\t CGroup: %s\n", i->default_control_group); if (arg_transport != TRANSPORT_SSH) { c = columns(); @@ -501,7 +463,7 @@ static void print_user_status_info(UserStatusInfo *i) { else c = 0; - show_cgroup_by_path(i->control_group, "\t\t ", c, false); + show_cgroup_by_path(i->default_control_group, "\t\t ", c, false, arg_all); } } } @@ -557,8 +519,8 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess i->id = s; else if (streq(name, "Name")) i->name = s; - else if (streq(name, "ControlGroupPath")) - i->control_group = s; + else if (streq(name, "DefaultControlGroup")) + i->default_control_group = s; else if (streq(name, "TTY")) i->tty = s; else if (streq(name, "Display")) @@ -571,6 +533,10 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess i->service = s; else if (streq(name, "Type")) i->type = s; + else if (streq(name, "Class")) + i->class = s; + else if (streq(name, "State")) + i->state = s; } break; } @@ -595,8 +561,6 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess if (streq(name, "Remote")) i->remote = b; - else if (streq(name, "Active")) - i->active = b; break; } @@ -654,8 +618,8 @@ static int status_property_user(const char *name, DBusMessageIter *iter, UserSta if (!isempty(s)) { if (streq(name, "Name")) i->name = s; - else if (streq(name, "ControlGroupPath")) - i->control_group = s; + else if (streq(name, "DefaultControlGroup")) + i->default_control_group = s; else if (streq(name, "State")) i->state = s; } @@ -881,16 +845,14 @@ static int print_property(const char *name, DBusMessageIter *iter) { } static int show_one(const char *verb, DBusConnection *bus, const char *path, bool show_properties, bool *new_line) { - DBusMessage *m = NULL, *reply = NULL; + _cleanup_dbus_message_unref_ DBusMessage *reply = NULL; const char *interface = ""; int r; - DBusError error; DBusMessageIter iter, sub, sub2, sub3; SessionStatusInfo session_info; UserStatusInfo user_info; SeatStatusInfo seat_info; - assert(bus); assert(path); assert(new_line); @@ -898,33 +860,18 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo zero(user_info); zero(seat_info); - dbus_error_init(&error); - - m = dbus_message_new_method_call( + r = bus_method_call_with_reply( + bus, "org.freedesktop.login1", path, "org.freedesktop.DBus.Properties", - "GetAll"); - if (!m) { - log_error("Could not allocate message."); - r = -ENOMEM; - goto finish; - } - - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &interface, - DBUS_TYPE_INVALID)) { - log_error("Could not append arguments to message."); - r = -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)); - r = -EIO; + "GetAll", + &reply, + NULL, + DBUS_TYPE_STRING, &interface, + DBUS_TYPE_INVALID); + if (r < 0) goto finish; - } if (!dbus_message_iter_init(reply, &iter) || dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || @@ -977,7 +924,6 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo if (r < 0) { log_error("Failed to parse reply."); - r = -EIO; goto finish; } @@ -993,25 +939,17 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo print_seat_status_info(&seat_info); } - strv_free(seat_info.sessions); - strv_free(user_info.sessions); - r = 0; finish: - if (m) - dbus_message_unref(m); - - if (reply) - dbus_message_unref(reply); - - dbus_error_free(&error); + strv_free(seat_info.sessions); + strv_free(user_info.sessions); return r; } static int show(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL, *reply = NULL; + DBusMessage *reply = NULL; int r, ret = 0; DBusError error; unsigned i; @@ -1024,8 +962,7 @@ static int show(DBusConnection *bus, char **args, unsigned n) { show_properties = !strstr(args[0], "status"); - if (show_properties) - pager_open_if_enabled(); + pager_open_if_enabled(); if (show_properties && n <= 1) { /* If not argument is specified inspect the manager @@ -1040,82 +977,53 @@ static int show(DBusConnection *bus, char **args, unsigned n) { if (strstr(args[0], "session")) { - m = dbus_message_new_method_call( + ret = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", - "GetSession"); - 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; - } + "GetSession", + &reply, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); } else if (strstr(args[0], "user")) { uid_t uid; uint32_t u; - ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL); if (ret < 0) { log_error("User %s unknown.", args[i]); goto finish; } - m = dbus_message_new_method_call( + u = (uint32_t) uid; + ret = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", - "GetUser"); - if (!m) { - log_error("Could not allocate message."); - ret = -ENOMEM; - goto finish; - } - - u = (uint32_t) 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; - } + "GetUser", + &reply, + NULL, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INVALID); } else { - m = dbus_message_new_method_call( + ret = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", - "GetSeat"); - 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; - } + "GetSeat", + &reply, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); } - - 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; + if (ret) goto finish; - } if (!dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &path, @@ -1129,15 +1037,11 @@ static int show(DBusConnection *bus, char **args, unsigned n) { if (r != 0) ret = r; - dbus_message_unref(m); dbus_message_unref(reply); - m = reply = NULL; + reply = NULL; } finish: - if (m) - dbus_message_unref(m); - if (reply) dbus_message_unref(reply); @@ -1147,482 +1051,265 @@ finish: } static int activate(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL; int ret = 0; - DBusError error; unsigned i; - assert(bus); assert(args); - dbus_error_init(&error); - for (i = 1; i < n; i++) { - DBusMessage *reply; - m = dbus_message_new_method_call( + ret = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", 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; + "ActivateSession", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + if (ret) 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); - - dbus_error_free(&error); - return ret; } static int kill_session(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL; int ret = 0; - DBusError error; unsigned i; - assert(bus); assert(args); - dbus_error_init(&error); - if (!arg_kill_who) arg_kill_who = "all"; for (i = 1; i < n; i++) { - DBusMessage *reply; - - m = dbus_message_new_method_call( + ret = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", - "KillSession"); - 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_STRING, &arg_kill_who, - DBUS_TYPE_INT32, arg_signal, - 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; + "KillSession", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_STRING, &arg_kill_who, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + if (ret) goto finish; - } - - dbus_message_unref(m); - dbus_message_unref(reply); - m = reply = NULL; } finish: - if (m) - dbus_message_unref(m); - - dbus_error_free(&error); - return ret; } static int enable_linger(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL; int ret = 0; - DBusError error; unsigned i; dbus_bool_t b, interactive = true; - assert(bus); assert(args); - dbus_error_init(&error); + polkit_agent_open_if_enabled(); b = streq(args[0], "enable-linger"); for (i = 1; i < n; i++) { - DBusMessage *reply; uint32_t u; uid_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; - } - - ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL); if (ret < 0) { log_error("Failed to resolve user %s: %s", args[i], strerror(-ret)); goto finish; } u = (uint32_t) uid; - if (!dbus_message_append_args(m, - DBUS_TYPE_UINT32, &u, - 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; + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "SetUserLinger", + NULL, + NULL, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); + if (ret) goto finish; - } - - dbus_message_unref(m); - dbus_message_unref(reply); - m = reply = NULL; } - ret = 0; - finish: - if (m) - dbus_message_unref(m); - - dbus_error_free(&error); - return ret; } static int terminate_user(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = 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; uid_t uid; - DBusMessage *reply; - - 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; - } - ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL); if (ret < 0) { log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); goto finish; } u = (uint32_t) 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; + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "TerminateUser", + NULL, + NULL, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INVALID); + if (ret) goto finish; - } - - dbus_message_unref(m); - dbus_message_unref(reply); - m = reply = NULL; } - ret = 0; - finish: - if (m) - dbus_message_unref(m); - - dbus_error_free(&error); - return ret; } static int kill_user(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL; int ret = 0; - DBusError error; unsigned i; - assert(bus); assert(args); - dbus_error_init(&error); - if (!arg_kill_who) arg_kill_who = "all"; for (i = 1; i < n; i++) { - DBusMessage *reply; uid_t uid; uint32_t u; - m = dbus_message_new_method_call( - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "KillUser"); - if (!m) { - log_error("Could not allocate message."); - ret = -ENOMEM; - goto finish; - } - - ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL, NULL); if (ret < 0) { log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); goto finish; } u = (uint32_t) uid; - if (!dbus_message_append_args(m, - DBUS_TYPE_UINT32, &u, - DBUS_TYPE_INT32, arg_signal, - 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; + ret = bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "KillUser", + NULL, + NULL, + DBUS_TYPE_UINT32, &u, + DBUS_TYPE_INT32, &arg_signal, + DBUS_TYPE_INVALID); + if (ret) goto finish; - } - - dbus_message_unref(m); - dbus_message_unref(reply); - m = reply = NULL; } - ret = 0; - finish: - if (m) - dbus_message_unref(m); - - dbus_error_free(&error); - return ret; } static int attach(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL; int ret = 0; - DBusError error; unsigned i; dbus_bool_t interactive = true; - assert(bus); assert(args); - dbus_error_init(&error); + polkit_agent_open_if_enabled(); for (i = 2; i < n; i++) { - DBusMessage *reply; - - m = dbus_message_new_method_call( + ret = bus_method_call_with_reply ( + bus, "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", - "AttachDevice"); - if (!m) { - log_error("Could not allocate message."); - ret = -ENOMEM; + "AttachDevice", + NULL, + NULL, + DBUS_TYPE_STRING, &args[1], + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); + if (ret) 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); - - dbus_error_free(&error); - return ret; } static int flush_devices(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL, *reply = NULL; - int ret = 0; - DBusError error; dbus_bool_t interactive = true; - assert(bus); assert(args); - dbus_error_init(&error); + polkit_agent_open_if_enabled(); - m = dbus_message_new_method_call( + return bus_method_call_with_reply ( + bus, "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); + "FlushDevices", + NULL, + NULL, + DBUS_TYPE_BOOLEAN, &interactive, + DBUS_TYPE_INVALID); +} - dbus_error_free(&error); +static int lock_sessions(DBusConnection *bus, char **args, unsigned n) { + polkit_agent_open_if_enabled(); - return ret; + return bus_method_call_with_reply ( + bus, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "LockSessions", + NULL, + NULL, + DBUS_TYPE_INVALID); } static int terminate_seat(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL; int ret = 0; - DBusError error; unsigned i; - assert(bus); assert(args); - dbus_error_init(&error); - for (i = 1; i < n; i++) { - DBusMessage *reply; - - m = dbus_message_new_method_call( + ret = bus_method_call_with_reply ( + bus, "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; + "TerminateSeat", + NULL, + NULL, + DBUS_TYPE_STRING, &args[i], + DBUS_TYPE_INVALID); + if (ret) goto finish; - } - - dbus_message_unref(m); - dbus_message_unref(reply); - m = reply = NULL; } finish: - if (m) - dbus_message_unref(m); - - dbus_error_free(&error); - return ret; } @@ -1630,16 +1317,16 @@ static int help(void) { printf("%s [OPTIONS...] {COMMAND} ...\n\n" "Send control commands to or query the login manager.\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " -p --property=NAME Show only properties by this name\n" - " -a --all Show all properties, including empty ones\n" - " --kill-who=WHO Who to send signal to\n" - " -s --signal=SIGNAL Which signal to send\n" - " -H --host=[USER@]HOST\n" - " Show information for remote host\n" - " -P --privileged Acquire privileges before execution\n" - " --no-pager Do not pipe output into a pager\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " -p --property=NAME Show only properties by this name\n" + " -a --all Show all properties, including empty ones\n" + " --kill-who=WHO Who to send signal to\n" + " -s --signal=SIGNAL Which signal to send\n" + " --no-ask-password Don't prompt for password\n" + " -H --host=[USER@]HOST Show information for remote host\n" + " -P --privileged Acquire privileges before execution\n" + " --no-pager Do not pipe output into a pager\n\n" "Commands:\n" " list-sessions List sessions\n" " session-status [ID...] Show session status\n" @@ -1647,6 +1334,7 @@ static int help(void) { " 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" + " lock-sessions Screen lock all current 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" @@ -1672,20 +1360,22 @@ static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_NO_PAGER, - ARG_KILL_WHO + ARG_KILL_WHO, + ARG_NO_ASK_PASSWORD }; static const struct option options[] = { - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, ARG_VERSION }, - { "property", required_argument, NULL, 'p' }, - { "all", no_argument, NULL, 'a' }, - { "no-pager", no_argument, NULL, ARG_NO_PAGER }, - { "kill-who", required_argument, NULL, ARG_KILL_WHO }, - { "signal", required_argument, NULL, 's' }, - { "host", required_argument, NULL, 'H' }, - { "privileged",no_argument, NULL, 'P' }, - { NULL, 0, NULL, 0 } + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, ARG_VERSION }, + { "property", required_argument, NULL, 'p' }, + { "all", no_argument, NULL, 'a' }, + { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "kill-who", required_argument, NULL, ARG_KILL_WHO }, + { "signal", required_argument, NULL, 's' }, + { "host", required_argument, NULL, 'H' }, + { "privileged", no_argument, NULL, 'P' }, + { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, + { NULL, 0, NULL, 0 } }; int c; @@ -1732,6 +1422,10 @@ static int parse_argv(int argc, char *argv[]) { arg_no_pager = true; break; + case ARG_NO_ASK_PASSWORD: + arg_ask_password = false; + break; + case ARG_KILL_WHO: arg_kill_who = optarg; break; @@ -1783,6 +1477,7 @@ static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "activate", EQUAL, 2, activate }, { "lock-session", MORE, 2, activate }, { "unlock-session", MORE, 2, activate }, + { "lock-sessions", EQUAL, 1, lock_sessions }, { "terminate-session", MORE, 2, activate }, { "kill-session", MORE, 2, kill_session }, { "list-users", EQUAL, 1, list_users },