logind: add virtual object paths that always can be used to refer to the callers session, user, seat or machine object

This way clients can skip invoking GetSessionByPID() for their own PID
or a similar call to access these objects.
This commit is contained in:
Lennart Poettering 2013-11-05 20:52:39 +01:00
parent d16bd05561
commit 927b164944
5 changed files with 157 additions and 77 deletions

View File

@ -254,10 +254,9 @@ const sd_bus_vtable seat_vtable[] = {
};
int seat_object_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
_cleanup_free_ char *e = NULL;
Manager *m = userdata;
Seat *seat;
const char *p;
int r;
assert(bus);
assert(path);
@ -265,17 +264,43 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
assert(found);
assert(m);
p = startswith(path, "/org/freedesktop/login1/seat/");
if (!p)
return 0;
if (streq(path, "/org/freedesktop/login1/seat/self")) {
sd_bus_message *message;
Session *session;
pid_t pid;
e = bus_path_unescape(p);
if (!e)
return -ENOMEM;
message = sd_bus_get_current(bus);
if (!message)
return 0;
seat = hashmap_get(m->seats, e);
if (!seat)
return 0;
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
if (r < 0)
return 0;
r = manager_get_session_by_pid(m, pid, &session);
if (r <= 0)
return 0;
if (!session->seat)
return 0;
seat = session->seat;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
p = startswith(path, "/org/freedesktop/login1/seat/");
if (!p)
return 0;
e = bus_path_unescape(p);
if (!e)
return -ENOMEM;
seat = hashmap_get(m->seats, e);
if (!seat)
return 0;
}
*found = seat;
return 1;

View File

@ -465,10 +465,9 @@ const sd_bus_vtable session_vtable[] = {
};
int session_object_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
_cleanup_free_ char *e = NULL;
Manager *m = userdata;
Session *session;
const char *p;
int r;
assert(bus);
assert(path);
@ -476,17 +475,37 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
assert(found);
assert(m);
p = startswith(path, "/org/freedesktop/login1/session/");
if (!p)
return 0;
if (streq(path, "/org/freedesktop/login1/session/self")) {
sd_bus_message *message;
pid_t pid;
e = bus_path_unescape(p);
if (!e)
return -ENOMEM;
message = sd_bus_get_current(bus);
if (!message)
return 0;
session = hashmap_get(m->sessions, e);
if (!session)
return 0;
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
if (r < 0)
return 0;
r = manager_get_session_by_pid(m, pid, &session);
if (r <= 0)
return 0;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
p = startswith(path, "/org/freedesktop/login1/session/");
if (!p)
return 0;
e = bus_path_unescape(p);
if (!e)
return -ENOMEM;
session = hashmap_get(m->sessions, e);
if (!session)
return 0;
}
*found = session;
return 1;

View File

@ -236,11 +236,7 @@ const sd_bus_vtable user_vtable[] = {
};
int user_object_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
_cleanup_free_ char *e = NULL;
Manager *m = userdata;
unsigned long lu;
const char *p;
User *user;
int r;
@ -250,17 +246,37 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void
assert(found);
assert(m);
p = startswith(path, "/org/freedesktop/login1/user/_");
if (!p)
return 0;
if (streq(path, "/org/freedesktop/login1/user/self")) {
sd_bus_message *message;
pid_t pid;
r = safe_atolu(p, &lu);
if (r < 0)
return 0;
message = sd_bus_get_current(bus);
if (!message)
return 0;
user = hashmap_get(m->users, ULONG_TO_PTR(lu));
if (!user)
return 0;
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
if (r < 0)
return 0;
r = manager_get_user_by_pid(m, pid, &user);
if (r <= 0)
return 0;
} else {
unsigned long lu;
const char *p;
p = startswith(path, "/org/freedesktop/login1/user/_");
if (!p)
return 0;
r = safe_atolu(p, &lu);
if (r < 0)
return 0;
user = hashmap_get(m->users, ULONG_TO_PTR(lu));
if (!user)
return 0;
}
*found = user;
return 1;

View File

@ -23,6 +23,7 @@
#include <string.h>
#include "bus-util.h"
#include "strv.h"
#include "machine.h"
static int property_get_id(
@ -142,10 +143,9 @@ const sd_bus_vtable machine_vtable[] = {
};
int machine_object_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
_cleanup_free_ char *e = NULL;
Manager *m = userdata;
Machine *machine;
const char *p;
int r;
assert(bus);
assert(path);
@ -153,17 +153,37 @@ int machine_object_find(sd_bus *bus, const char *path, const char *interface, vo
assert(found);
assert(m);
p = startswith(path, "/org/freedesktop/machine1/machine/");
if (!p)
return 0;
if (streq(path, "/org/freedesktop/machine1/machine/self")) {
sd_bus_message *message;
pid_t pid;
e = bus_path_unescape(p);
if (!e)
return -ENOMEM;
message = sd_bus_get_current(bus);
if (!message)
return 0;
machine = hashmap_get(m->machines, e);
if (!machine)
return 0;
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
if (r < 0)
return 0;
r = manager_get_machine_by_pid(m, pid, &machine);
if (r <= 0)
return 0;
} else {
_cleanup_free_ char *e = NULL;
const char *p;
p = startswith(path, "/org/freedesktop/machine1/machine/");
if (!p)
return 0;
e = bus_path_unescape(p);
if (!e)
return -ENOMEM;
machine = hashmap_get(m->machines, e);
if (!machine)
return 0;
}
*found = machine;
return 1;
@ -181,6 +201,37 @@ char *machine_bus_path(Machine *m) {
return strappend("/org/freedesktop/machine1/machine/", e);
}
int machine_node_enumerator(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
_cleanup_strv_free_ char **l = NULL;
Machine *machine = NULL;
Manager *m = userdata;
Iterator i;
int r;
assert(bus);
assert(path);
assert(nodes);
HASHMAP_FOREACH(machine, m->machines, i) {
char *p;
p = machine_bus_path(machine);
if (!p)
return -ENOMEM;
r = strv_push(&l, p);
if (r < 0) {
free(p);
return r;
}
}
*nodes = l;
l = NULL;
return 1;
}
int machine_send_signal(Machine *m, bool new_machine) {
_cleanup_free_ char *p = NULL;

View File

@ -342,37 +342,6 @@ const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_END
};
int machine_node_enumerator(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
_cleanup_strv_free_ char **l = NULL;
Machine *machine = NULL;
Manager *m = userdata;
Iterator i;
int r;
assert(bus);
assert(path);
assert(nodes);
HASHMAP_FOREACH(machine, m->machines, i) {
char *p;
p = machine_bus_path(machine);
if (!p)
return -ENOMEM;
r = strv_push(&l, p);
if (r < 0) {
free(p);
return r;
}
}
*nodes = l;
l = NULL;
return 1;
}
int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata) {
const char *path, *result, *unit;
Manager *m = userdata;