diff options
Diffstat (limited to '')
-rw-r--r-- | src/home/homed-bus.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/home/homed-bus.c b/src/home/homed-bus.c index 24b421a..a6f26fe 100644 --- a/src/home/homed-bus.c +++ b/src/home/homed-bus.c @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "fd-util.h" +#include "home-util.h" #include "homed-bus.h" +#include "stat-util.h" #include "strv.h" int bus_message_read_secret(sd_bus_message *m, UserRecord **ret, sd_bus_error *error) { @@ -64,3 +67,70 @@ int bus_message_read_home_record(sd_bus_message *m, UserRecordLoadFlags flags, U *ret = TAKE_PTR(hr); return 0; } + +int bus_message_read_blobs(sd_bus_message *m, Hashmap **ret, sd_bus_error *error) { + _cleanup_hashmap_free_ Hashmap *blobs = NULL; + int r; + + assert(m); + assert(ret); + + /* We want to differentiate between blobs being NULL (not passed at all) + * and empty (passed from dbus, but it was empty) */ + r = hashmap_ensure_allocated(&blobs, &blob_fd_hash_ops); + if (r < 0) + return r; + + r = sd_bus_message_enter_container(m, 'a', "{sh}"); + if (r < 0) + return r; + + for (;;) { + _cleanup_free_ char *filename = NULL; + _cleanup_close_ int fd = -EBADF; + const char *_filename = NULL; + int _fd; + + r = sd_bus_message_read(m, "{sh}", &_filename, &_fd); + if (r < 0) + return r; + if (r == 0) + break; + + filename = strdup(_filename); + if (!filename) + return -ENOMEM; + + fd = fcntl(_fd, F_DUPFD_CLOEXEC, 3); + if (fd < 0) + return -errno; + + r = suitable_blob_filename(filename); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid blob directory filename: %s", filename); + + r = fd_verify_regular(fd); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "FD for '%s' is not a regular file", filename); + + r = fd_verify_safe_flags(fd); + if (r == -EREMOTEIO) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, + "FD for '%s' has unexpected flags set", filename); + if (r < 0) + return r; + + r = hashmap_put(blobs, filename, FD_TO_PTR(fd)); + if (r < 0) + return r; + TAKE_PTR(filename); /* Ownership transferred to hashmap */ + TAKE_FD(fd); + } + + r = sd_bus_message_exit_container(m); + if (r < 0) + return r; + + *ret = TAKE_PTR(blobs); + return 0; +} |