summaryrefslogtreecommitdiffstats
path: root/src/home/homed-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/home/homed-manager.c')
-rw-r--r--src/home/homed-manager.c71
1 files changed, 55 insertions, 16 deletions
diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c
index b8bef53..7669cbb 100644
--- a/src/home/homed-manager.c
+++ b/src/home/homed-manager.c
@@ -42,6 +42,7 @@
#include "quota-util.h"
#include "random-util.h"
#include "resize-fs.h"
+#include "rm-rf.h"
#include "socket-util.h"
#include "sort-util.h"
#include "stat-util.h"
@@ -79,6 +80,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_sysfs_hash_ops, char, pat
static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata);
static int manager_gc_images(Manager *m);
+static int manager_gc_blob(Manager *m);
static int manager_enumerate_images(Manager *m);
static int manager_assess_image(Manager *m, int dir_fd, const char *dir_path, const char *dentry_name);
static void manager_revalidate_image(Manager *m, Home *h);
@@ -268,7 +270,7 @@ Manager* manager_free(Manager *m) {
(void) home_wait_for_worker(h);
m->bus = sd_bus_flush_close_unref(m->bus);
- m->polkit_registry = bus_verify_polkit_async_registry_free(m->polkit_registry);
+ m->polkit_registry = hashmap_free(m->polkit_registry);
m->device_monitor = sd_device_monitor_unref(m->device_monitor);
@@ -588,8 +590,8 @@ static int manager_acquire_uid(
assert(ret);
for (;;) {
- struct passwd *pw;
- struct group *gr;
+ _cleanup_free_ struct passwd *pw = NULL;
+ _cleanup_free_ struct group *gr = NULL;
uid_t candidate;
Home *other;
@@ -632,19 +634,27 @@ static int manager_acquire_uid(
continue;
}
- pw = getpwuid(candidate);
- if (pw) {
+ r = getpwuid_malloc(candidate, &pw);
+ if (r >= 0) {
log_debug("Candidate UID " UID_FMT " already registered by another user in NSS (%s), let's try another.",
candidate, pw->pw_name);
continue;
}
+ if (r != -ESRCH) {
+ log_debug_errno(r, "Failed to check if an NSS user is already registered for candidate UID " UID_FMT ", assuming there might be: %m", candidate);
+ continue;
+ }
- gr = getgrgid((gid_t) candidate);
- if (gr) {
+ r = getgrgid_malloc((gid_t) candidate, &gr);
+ if (r >= 0) {
log_debug("Candidate UID " UID_FMT " already registered by another group in NSS (%s), let's try another.",
candidate, gr->gr_name);
continue;
}
+ if (r != -ESRCH) {
+ log_debug_errno(r, "Failed to check if an NSS group is already registered for candidate UID " UID_FMT ", assuming there might be: %m", candidate);
+ continue;
+ }
r = search_ipc(candidate, (gid_t) candidate);
if (r < 0)
@@ -715,7 +725,7 @@ static int manager_add_home_by_image(
}
} else {
/* Check NSS, in case there's another user or group by this name */
- if (getpwnam(user_name) || getgrnam(user_name)) {
+ if (getpwnam_malloc(user_name, /* ret= */ NULL) >= 0 || getgrnam_malloc(user_name, /* ret= */ NULL) >= 0) {
log_debug("Found an existing user or group by name '%s', ignoring image '%s'.", user_name, image_path);
return 0;
}
@@ -903,7 +913,7 @@ static int manager_assess_image(
r = btrfs_is_subvol_fd(fd);
if (r < 0)
- return log_warning_errno(errno, "Failed to determine whether %s is a btrfs subvolume: %m", path);
+ return log_warning_errno(r, "Failed to determine whether %s is a btrfs subvolume: %m", path);
if (r > 0)
storage = USER_SUBVOLUME;
else {
@@ -981,7 +991,7 @@ static int manager_connect_bus(Manager *m) {
if (r < 0)
return log_error_errno(r, "Failed to request name: %m");
- r = sd_bus_attach_event(m->bus, m->event, 0);
+ r = sd_bus_attach_event(m->bus, m->event, SD_EVENT_PRIORITY_NORMAL);
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
@@ -998,7 +1008,7 @@ static int manager_bind_varlink(Manager *m) {
assert(m);
assert(!m->varlink_server);
- r = varlink_server_new(&m->varlink_server, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA);
+ r = varlink_server_new(&m->varlink_server, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA|VARLINK_SERVER_INPUT_SENSITIVE);
if (r < 0)
return log_error_errno(r, "Failed to allocate varlink server object: %m");
@@ -1044,7 +1054,7 @@ static int manager_bind_varlink(Manager *m) {
/* Avoid recursion */
if (setenv("SYSTEMD_BYPASS_USERDB", m->userdb_service, 1) < 0)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set $SYSTEMD_BYPASS_USERDB: %m");
+ return log_error_errno(errno, "Failed to set $SYSTEMD_BYPASS_USERDB: %m");
return 0;
}
@@ -1355,8 +1365,11 @@ static int manager_enumerate_devices(Manager *m) {
if (r < 0)
return r;
- FOREACH_DEVICE(e, d)
+ FOREACH_DEVICE(e, d) {
+ if (device_is_processed(d) <= 0)
+ continue;
(void) manager_add_device(m, d);
+ }
return 0;
}
@@ -1428,7 +1441,7 @@ static int manager_generate_key_pair(Manager *m) {
/* Write out public key (note that we only do that as a help to the user, we don't make use of this ever */
r = fopen_temporary("/var/lib/systemd/home/local.public", &fpublic, &temp_public);
if (r < 0)
- return log_error_errno(errno, "Failed to open key file for writing: %m");
+ return log_error_errno(r, "Failed to open key file for writing: %m");
if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
@@ -1442,7 +1455,7 @@ static int manager_generate_key_pair(Manager *m) {
/* Write out the private key (this actually writes out both private and public, OpenSSL is confusing) */
r = fopen_temporary("/var/lib/systemd/home/local.private", &fprivate, &temp_private);
if (r < 0)
- return log_error_errno(errno, "Failed to open key file for writing: %m");
+ return log_error_errno(r, "Failed to open key file for writing: %m");
if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, 0) <= 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair.");
@@ -1619,6 +1632,9 @@ int manager_startup(Manager *m) {
/* Let's clean up home directories whose devices got removed while we were not running */
(void) manager_enqueue_gc(m, NULL);
+ /* Let's clean up blob directories for home dirs that no longer exist */
+ (void) manager_gc_blob(m);
+
return 0;
}
@@ -1707,6 +1723,29 @@ int manager_gc_images(Manager *m) {
return 0;
}
+static int manager_gc_blob(Manager *m) {
+ _cleanup_closedir_ DIR *d = NULL;
+ int r;
+
+ assert(m);
+
+ d = opendir(home_system_blob_dir());
+ if (!d) {
+ if (errno == ENOENT)
+ return 0;
+ return log_error_errno(errno, "Failed to open %s: %m", home_system_blob_dir());
+ }
+
+ FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read system blob directory: %m"))
+ if (!hashmap_contains(m->homes_by_name, de->d_name)) {
+ r = rm_rf_at(dirfd(d), de->d_name, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
+ if (r < 0)
+ log_warning_errno(r, "Failed to delete blob dir for missing user '%s', ignoring: %m", de->d_name);
+ }
+
+ return 0;
+}
+
static int on_deferred_rescan(sd_event_source *s, void *userdata) {
Manager *m = ASSERT_PTR(userdata);
@@ -1989,7 +2028,7 @@ static int manager_rebalance_apply(Manager *m) {
h->rebalance_pending = false;
- r = home_resize(h, h->rebalance_goal, /* secret= */ NULL, /* automatic= */ true, &error);
+ r = home_resize(h, h->rebalance_goal, /* secret= */ NULL, &error);
if (r < 0)
log_warning_errno(r, "Failed to resize home '%s' for rebalancing, ignoring: %s",
h->user_name, bus_error_message(&error, r));