homed: add bus call that allows referencing a home without activating it

This is useful for allowing users to login without the ability to unlock
their home dir. Usecase is ssh: ssh might grant access without giving
us the chance to unlock the home dir for the user (because it doesn't
allow us asking questions during authentication), hence with this call
we can pin the home dir, but not activate it and then allow the
activation to be delayed until later.
This commit is contained in:
Lennart Poettering
2023-11-27 17:08:17 +01:00
parent 2f4aa81440
commit 508d344e0e
3 changed files with 41 additions and 15 deletions

View File

@@ -620,30 +620,38 @@ int bus_home_method_ref(
_cleanup_close_ int fd = -EBADF;
Home *h = ASSERT_PTR(userdata);
HomeState state;
int please_suspend, r;
bool unrestricted;
assert(message);
/* In unrestricted mode we'll add a reference to the home even if it's not active */
unrestricted = strstr(sd_bus_message_get_member(message), "Unrestricted");
r = sd_bus_message_read(message, "b", &please_suspend);
if (r < 0)
return r;
state = home_get_state(h);
switch (state) {
case HOME_ABSENT:
return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
case HOME_UNFIXATED:
case HOME_INACTIVE:
case HOME_DIRTY:
return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s not active.", h->user_name);
case HOME_LOCKED:
return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
default:
if (HOME_STATE_IS_ACTIVE(state))
break;
if (!unrestricted) {
HomeState state;
return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
state = home_get_state(h);
switch (state) {
case HOME_ABSENT:
return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
case HOME_UNFIXATED:
case HOME_INACTIVE:
case HOME_DIRTY:
return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s not active.", h->user_name);
case HOME_LOCKED:
return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
default:
if (HOME_STATE_IS_ACTIVE(state))
break;
return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
}
}
fd = home_create_fifo(h, please_suspend ? HOME_FIFO_PLEASE_SUSPEND : HOME_FIFO_DONT_SUSPEND);
@@ -865,6 +873,11 @@ const sd_bus_vtable home_vtable[] = {
SD_BUS_RESULT("h", send_fd),
bus_home_method_ref,
0),
SD_BUS_METHOD_WITH_ARGS("RefUnrestricted",
SD_BUS_ARGS("b", please_suspend),
SD_BUS_RESULT("h", send_fd),
bus_home_method_ref,
0),
SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0),
SD_BUS_METHOD_WITH_ARGS("InhibitSuspend",
SD_BUS_NO_ARGS,

View File

@@ -843,6 +843,11 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_RESULT("h", send_fd),
method_ref_home,
0),
SD_BUS_METHOD_WITH_ARGS("RefHomeUnrestricted",
SD_BUS_ARGS("s", user_name, "b", please_suspend),
SD_BUS_RESULT("h", send_fd),
method_ref_home,
0),
SD_BUS_METHOD_WITH_ARGS("ReleaseHome",
SD_BUS_ARGS("s", user_name),
SD_BUS_NO_RESULT,

View File

@@ -117,6 +117,10 @@
send_interface="org.freedesktop.home1.Manager"
send_member="RefHome"/>
<allow send_destination="org.freedesktop.home1"
send_interface="org.freedesktop.home1.Manager"
send_member="RefHomeUnrestricted"/>
<allow send_destination="org.freedesktop.home1"
send_interface="org.freedesktop.home1.Manager"
send_member="ReleaseHome"/>
@@ -195,6 +199,10 @@
send_interface="org.freedesktop.home1.Home"
send_member="Ref"/>
<allow send_destination="org.freedesktop.home1"
send_interface="org.freedesktop.home1.Home"
send_member="RefUnrestricted"/>
<allow send_destination="org.freedesktop.home1"
send_interface="org.freedesktop.home1.Home"
send_member="Release"/>