summaryrefslogtreecommitdiffstats
path: root/src/home/homed-bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/home/homed-bus.c')
-rw-r--r--src/home/homed-bus.c70
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;
+}