mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-29 21:47:05 +03:00
loginctl: implement more verbs
This commit is contained in:
parent
d4b36d99f1
commit
88e3dc903b
323
src/loginctl.c
323
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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user