]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/home/user-record-util.c
homed: Create & advertise blob directory
[thirdparty/systemd.git] / src / home / user-record-util.c
index 6a892d45b5b4730b7280c795a7f4227b2b4ad28c..b18a77d7407e98b1b44acc1224d06ef67c0eb644 100644 (file)
@@ -282,7 +282,7 @@ int user_record_add_binding(
                 gid_t gid) {
 
         _cleanup_(json_variant_unrefp) JsonVariant *new_binding_entry = NULL, *binding = NULL;
-        _cleanup_free_ char *ip = NULL, *hd = NULL, *ip_auto = NULL, *lc = NULL, *lcm = NULL, *fst = NULL;
+        _cleanup_free_ char *blob = NULL, *ip = NULL, *hd = NULL, *ip_auto = NULL, *lc = NULL, *lcm = NULL, *fst = NULL;
         sd_id128_t mid;
         int r;
 
@@ -291,6 +291,10 @@ int user_record_add_binding(
         if (!h->json)
                 return -EUNATCH;
 
+        blob = path_join(home_system_blob_dir(), h->user_name);
+        if (!blob)
+                return -ENOMEM;
+
         r = sd_id128_get_machine(&mid);
         if (r < 0)
                 return r;
@@ -331,6 +335,7 @@ int user_record_add_binding(
 
         r = json_build(&new_binding_entry,
                        JSON_BUILD_OBJECT(
+                                       JSON_BUILD_PAIR("blobDirectory", JSON_BUILD_STRING(blob)),
                                        JSON_BUILD_PAIR_CONDITION(!!image_path, "imagePath", JSON_BUILD_STRING(image_path)),
                                        JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(partition_uuid), "partitionUuid", JSON_BUILD_STRING(SD_ID128_TO_UUID_STRING(partition_uuid))),
                                        JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(luks_uuid), "luksUuid", JSON_BUILD_STRING(SD_ID128_TO_UUID_STRING(luks_uuid))),
@@ -353,7 +358,7 @@ int user_record_add_binding(
                 /* Merge the new entry with an old one, if that exists */
                 be = json_variant_ref(json_variant_by_key(binding, SD_ID128_TO_STRING(mid)));
                 if (be) {
-                        r = json_variant_merge(&be, new_binding_entry);
+                        r = json_variant_merge_object(&be, new_binding_entry);
                         if (r < 0)
                                 return r;
 
@@ -370,6 +375,8 @@ int user_record_add_binding(
         if (r < 0)
                 return r;
 
+        free_and_replace(h->blob_directory, blob);
+
         if (storage >= 0)
                 h->storage = storage;
 
@@ -428,7 +435,7 @@ int user_record_test_home_directory(UserRecord *h) {
         if (r == 0)
                 return -ENOTDIR;
 
-        r = path_is_mount_point(hd, NULL, 0);
+        r = path_is_mount_point(hd);
         if (r < 0)
                 return r;
         if (r > 0)
@@ -445,7 +452,7 @@ int user_record_test_home_directory(UserRecord *h) {
         }
 
         /* Otherwise it's not OK */
-        r = dir_is_empty(hd);
+        r = dir_is_empty(hd, /* ignore_hidden_or_backup= */ false);
         if (r < 0)
                 return r;
         if (r == 0)
@@ -501,7 +508,7 @@ int user_record_test_image_path(UserRecord *h) {
 
                         n = getxattr(ip, "user.home-dirty", x, sizeof(x));
                         if (n < 0) {
-                                if (errno != ENODATA)
+                                if (!ERRNO_IS_XATTR_ABSENT(errno))
                                         log_debug_errno(errno, "Unable to read dirty xattr off image file, ignoring: %m");
 
                         } else if (n == 1 && x[0] == '1')
@@ -563,7 +570,6 @@ int user_record_test_image_path_and_warn(UserRecord *h) {
 }
 
 int user_record_test_password(UserRecord *h, UserRecord *secret) {
-        char **i;
         int r;
 
         assert(h);
@@ -585,7 +591,6 @@ int user_record_test_password(UserRecord *h, UserRecord *secret) {
 }
 
 int user_record_test_recovery_key(UserRecord *h, UserRecord *secret) {
-        char **i;
         int r;
 
         assert(h);
@@ -779,7 +784,6 @@ int user_record_update_last_changed(UserRecord *h, bool with_password) {
 int user_record_make_hashed_password(UserRecord *h, char **secret, bool extend) {
         _cleanup_(json_variant_unrefp) JsonVariant *priv = NULL;
         _cleanup_strv_free_ char **np = NULL;
-        char **i;
         int r;
 
         assert(h);
@@ -874,7 +878,7 @@ int user_record_set_hashed_password(UserRecord *h, char **hashed_password) {
 
 int user_record_set_password(UserRecord *h, char **password, bool prepend) {
         _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
-        _cleanup_(strv_free_erasep) char **e = NULL;
+        _cleanup_strv_free_erase_ char **e = NULL;
         int r;
 
         assert(h);
@@ -936,7 +940,7 @@ int user_record_set_password(UserRecord *h, char **password, bool prepend) {
 
 int user_record_set_token_pin(UserRecord *h, char **pin, bool prepend) {
         _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
-        _cleanup_(strv_free_erasep) char **e = NULL;
+        _cleanup_strv_free_erase_ char **e = NULL;
         int r;
 
         assert(h);
@@ -1158,6 +1162,7 @@ int user_record_merge_secret(UserRecord *h, UserRecord *secret) {
         int r;
 
         assert(h);
+        assert(secret);
 
         /* Merges the secrets from 'secret' into 'h'. */
 
@@ -1385,6 +1390,12 @@ int user_record_is_supported(UserRecord *hr, sd_bus_error *error) {
         if (hr->service && !streq(hr->service, "io.systemd.Home"))
                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Not accepted with service not matching io.systemd.Home.");
 
+        if (hr->blob_directory) {
+                /* This function is always called w/o binding section, so if hr->blob_dir is set then the caller set it themselves */
+                assert((hr->mask & USER_RECORD_BINDING) == 0);
+                return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot manage custom blob directories.");
+        }
+
         return 0;
 }