return r;
}
-static int load_credential_one(int credential_dir_fd, const char *name, int userdb_dir_fd) {
+static int load_credential_one(
+ int credential_dir_fd,
+ const char *name,
+ int userdb_dir_persist_fd,
+ int userdb_dir_transient_fd) {
+
int r;
assert(credential_dir_fd >= 0);
assert(name);
- assert(userdb_dir_fd >= 0);
+ assert(userdb_dir_persist_fd >= 0);
+ assert(userdb_dir_transient_fd >= 0);
+
+ const char *suffix = startswith(name, "userdb.");
+ if (!suffix)
+ return 0;
- const char *user = startswith(name, "userdb.user.");
- const char *group = startswith(name, "userdb.group.");
+ const char *transient = startswith(suffix, "transient."),
+ *user = startswith(transient ?: suffix, "user."),
+ *group = startswith(transient ?: suffix, "group.");
if (!user && !group)
return 0;
+ const char *userdb_dir = transient ? "/run/userdb" : "/etc/userdb";
+ int userdb_dir_fd = transient ? userdb_dir_transient_fd : userdb_dir_persist_fd;
+
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
unsigned line = 0, column = 0;
r = sd_json_parse_file_at(NULL, credential_dir_fd, name, SD_JSON_PARSE_SENSITIVE, &v, &line, &column);
r = write_string_file_at(userdb_dir_fd, fn, formatted, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
if (r < 0)
- return log_error_errno(r, "Failed to write JSON record to /etc/userdb/%s: %m", fn);
+ return log_error_errno(r, "Failed to write JSON record to %s/%s: %m", userdb_dir, fn);
if (symlinkat(fn, userdb_dir_fd, link) < 0)
return log_error_errno(errno, "Failed to create symlink from %s to %s: %m", link, fn);
- log_info("Installed /etc/userdb/%s from credential.", fn);
+ log_info("Installed %s/%s from credential.", userdb_dir, fn);
if ((ur && !sd_json_variant_is_blank_object(ur_privileged->json)) ||
(gr && !sd_json_variant_is_blank_object(gr_privileged->json))) {
r = write_string_file_at(userdb_dir_fd, fn, formatted, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_MODE_0600);
if (r < 0)
- return log_error_errno(r, "Failed to write JSON record to /etc/userdb/%s: %m", fn);
+ return log_error_errno(r, "Failed to write JSON record to %s/%s: %m", userdb_dir, fn);
link = mfree(link);
if (symlinkat(fn, userdb_dir_fd, link) < 0)
return log_error_errno(errno, "Failed to create symlink from %s to %s: %m", link, fn);
- log_info("Installed /etc/userdb/%s from credential.", fn);
+ log_info("Installed %s/%s from credential.", userdb_dir, fn);
}
if (ur)
if (fd < 0)
return log_error_errno(errno, "Failed to create %s: %m", membership);
- log_info("Installed /etc/userdb/%s from credential.", membership);
+ log_info("Installed %s/%s from credential.", userdb_dir, membership);
}
else
STRV_FOREACH(u, gr->members) {
if (fd < 0)
return log_error_errno(errno, "Failed to create %s: %m", membership);
- log_info("Installed /etc/userdb/%s from credential.", membership);
+ log_info("Installed %s/%s from credential.", userdb_dir, membership);
}
if (ur && user_record_disposition(ur) == USER_REGULAR) {
if (r < 0)
return log_error_errno(r, "Failed to enumerate credentials: %m");
- _cleanup_close_ int userdb_dir_fd = xopenat_full(
- AT_FDCWD, "/etc/userdb",
- /* open_flags= */ O_DIRECTORY|O_CREAT|O_CLOEXEC,
- /* xopen_flags= */ XO_LABEL,
- /* mode= */ 0755);
- if (userdb_dir_fd < 0)
- return log_error_errno(userdb_dir_fd, "Failed to open %s: %m", "/etc/userdb/");
+ _cleanup_close_ int userdb_persist_dir_fd = xopenat_full(
+ AT_FDCWD, "/etc/userdb",
+ /* open_flags= */ O_DIRECTORY|O_CREAT|O_CLOEXEC,
+ /* xopen_flags= */ XO_LABEL,
+ /* mode= */ 0755);
+ if (userdb_persist_dir_fd < 0)
+ return log_error_errno(userdb_persist_dir_fd, "Failed to open /etc/userdb/: %m");
+
+ _cleanup_close_ int userdb_transient_dir_fd = xopenat_full(
+ AT_FDCWD, "/run/userdb",
+ /* open_flags= */ O_DIRECTORY|O_CREAT|O_CLOEXEC,
+ /* xopen_flags= */ XO_LABEL,
+ /* mode= */ 0755);
+ if (userdb_transient_dir_fd < 0)
+ return log_error_errno(userdb_transient_dir_fd, "Failed to open /run/userdb/: %m");
FOREACH_ARRAY(i, des->entries, des->n_entries) {
struct dirent *de = *i;
if (de->d_type != DT_REG)
continue;
- RET_GATHER(r, load_credential_one(credential_dir_fd, de->d_name, userdb_dir_fd));
+ RET_GATHER(r, load_credential_one(
+ credential_dir_fd,
+ de->d_name,
+ userdb_persist_dir_fd,
+ userdb_transient_dir_fd));
}
return r;