diff options
Diffstat (limited to '')
-rw-r--r-- | src/home/homed-manager.c | 71 |
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)); |