return NOLOGIN;
}
+static int read_shell_credential(const Item *i, char **ret) {
+ _cleanup_free_ char *cn = NULL, *shell = NULL;
+ int r;
+
+ assert(i);
+
+ cn = strjoin("passwd.shell.", i->name);
+ if (!cn)
+ return -ENOMEM;
+
+ r = read_credential(cn, (void**) &shell, /* ret_size= */ NULL);
+ if (r < 0) {
+ log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
+ if (ret)
+ *ret = NULL;
+ return 0;
+ }
+
+ path_simplify(shell);
+ if (!valid_shell(shell))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Shell credential '%s' specifies invalid login shell '%s'.",
+ cn, shell);
+
+ if (ret)
+ *ret = TAKE_PTR(shell);
+ return 0;
+}
+
static int write_temporary_passwd(
Context *c,
const char *passwd_path,
goto done;
if (arg_dry_run) {
+ ORDERED_HASHMAP_FOREACH(i, c->todo_uids) {
+ r = read_shell_credential(i, /* ret= */ NULL);
+ if (r < 0)
+ return r;
+ }
+
log_info("Would write /etc/passwd%s", glyph(GLYPH_ELLIPSIS));
goto done;
}
}
ORDERED_HASHMAP_FOREACH(i, c->todo_uids) {
- _cleanup_free_ char *creds_shell = NULL, *cn = NULL;
+ _cleanup_free_ char *creds_shell = NULL;
struct passwd n = {
.pw_name = i->name,
.pw_shell = (char*) pick_shell(i),
};
- /* Try to pick up the shell for this account via the credentials logic */
- cn = strjoin("passwd.shell.", i->name);
- if (!cn)
- return -ENOMEM;
-
- r = read_credential(cn, (void**) &creds_shell, NULL);
+ r = read_shell_credential(i, &creds_shell);
if (r < 0)
- log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
- else
+ return r;
+ if (creds_shell)
n.pw_shell = creds_shell;
r = putpwent_sane(&n, passwd);
trap at_exit EXIT
+root="$(mktemp -d)"
+cred="$(mktemp -d)"
+mkdir -p "$root/etc"
+printf 'relative-shell' >"$cred/passwd.shell.creduser"
+(! env CREDENTIALS_DIRECTORY="$cred" systemd-sysusers --dry-run --root="$root" --inline 'u creduser 999 "Cred User" / -')
+(! env CREDENTIALS_DIRECTORY="$cred" systemd-sysusers --root="$root" --inline 'u creduser 999 "Cred User" / -')
+(! grep -F creduser "$root/etc/passwd" >/dev/null 2>&1)
+rm -rf "$root" "$cred"
+
# Ensure that a non-responsive NSS socket doesn't make sysusers fail
mount -t tmpfs tmpfs /run/systemd/userdb/
touch /run/systemd/userdb/io.systemd.DynamicUser