X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Floginctl.c;h=89762b66b01cf8f9592ba417313d4ec6eaccc2fe;hb=66ccd0387e528567dff92239e85c962d2f140ef1;hp=23c998cba2c7bab2cd27e940196c28f3a09a919d;hpb=7e2bb92dcae6ee785ff7462aadc8c369fd93715b;p=elogind.git diff --git a/src/loginctl.c b/src/loginctl.c index 23c998cba..89762b66b 100644 --- a/src/loginctl.c +++ b/src/loginctl.c @@ -64,6 +64,8 @@ static bool on_tty(void) { } static void pager_open_if_enabled(void) { + + /* Cache result before we open the pager */ on_tty(); if (!arg_no_pager) @@ -527,14 +529,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); } } @@ -1059,19 +1060,13 @@ static int show(DBusConnection *bus, char **args, unsigned n) { } } else if (strstr(args[0], "user")) { - uint32_t uid; - - if (safe_atou(args[i], &uid) < 0) { - struct passwd *pw; - - pw = getpwnam(args[i]); - if (!pw) { - log_error("User %s unknown.", args[i]); - ret = -ENOENT; - goto finish; - } + uid_t uid; + uint32_t u; - uid = pw->pw_uid; + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (ret < 0) { + log_error("User %s unknown.", args[i]); + goto finish; } m = dbus_message_new_method_call( @@ -1085,8 +1080,9 @@ static int show(DBusConnection *bus, char **args, unsigned n) { goto finish; } + u = (uint32_t) uid; if (!dbus_message_append_args(m, - DBUS_TYPE_UINT32, &uid, + DBUS_TYPE_UINT32, &u, DBUS_TYPE_INVALID)) { log_error("Could not append arguments to message."); ret = -ENOMEM; @@ -1151,7 +1147,7 @@ finish: } static int activate(DBusConnection *bus, char **args, unsigned n) { - DBusMessage *m = NULL, *reply = NULL; + DBusMessage *m = NULL; int ret = 0; DBusError error; unsigned i; @@ -1162,11 +1158,16 @@ static int activate(DBusConnection *bus, char **args, unsigned n) { dbus_error_init(&error); for (i = 1; i < n; i++) { + DBusMessage *reply; + m = dbus_message_new_method_call( "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; @@ -1197,32 +1198,432 @@ finish: if (m) dbus_message_unref(m); - if (reply) - dbus_message_unref(reply); - dbus_error_free(&error); return ret; } static int kill_session(DBusConnection *bus, char **args, unsigned n) { - return 0; + 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( + "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; + 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) { - return 0; + DBusMessage *m = 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++) { + 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); + 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; + 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); + 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; + 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); + 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; + 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) { - return 0; + DBusMessage *m = 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++) { + DBusMessage *reply; + + 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); + + 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; + 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( + "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); + + dbus_error_free(&error); + + return ret; } static int help(void) { @@ -1242,25 +1643,25 @@ static int help(void) { "Commands:\n" " list-sessions List sessions\n" " session-status [ID...] Show session status\n" - " show-session [ID...] Show property of one or more sessions\n" + " show-session [ID...] Show properties 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" " user-status [USER...] Show user status\n" - " show-user [USER...] Show property of one or more users\n" + " show-user [USER...] Show properties of one or more users\n" " enable-linger [USER...] Enable linger state of one or more users\n" " disable-linger [USER...] Disable linger state of one or more users\n" " terminate-user [USER...] Terminate all sessions of one or more users\n" " kill-user [USER...] Send signal to processes of a user\n" " list-seats List seats\n" " seat-status [NAME...] Show seat status\n" - " show-seat [NAME...] Show property of one or more seats\n" + " show-seat [NAME...] Show properties of one or more seats\n" " attach [NAME] [DEVICE...] Attach one or more devices to a seat\n" " flush-devices Flush all device associations\n" - " terminate-seat [NAME...] Terminate all sessions on one or more seats\n" - " kill-seat [NAME...] Send signal to processes of sessions on a seat\n", + " terminate-seat [NAME...] Terminate all sessions on one or more seats\n", program_invocation_short_name); return 0; @@ -1381,6 +1782,7 @@ 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 }, { "list-users", EQUAL, 1, list_users }, @@ -1388,15 +1790,14 @@ static int loginctl_main(DBusConnection *bus, int argc, char *argv[], DBusError { "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_user }, { "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 }, }; int left;