1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-27 18:04:05 +03:00

firstboot: Add --root-password-hashed option

This commit is contained in:
Daan De Meyer 2020-05-25 19:24:07 +02:00
parent 97a1a1103c
commit 676339a191
2 changed files with 90 additions and 69 deletions

View File

@ -150,18 +150,18 @@
<varlistentry> <varlistentry>
<term><option>--root-password=<replaceable>PASSWORD</replaceable></option></term> <term><option>--root-password=<replaceable>PASSWORD</replaceable></option></term>
<term><option>--root-password-file=<replaceable>PATH</replaceable></option></term> <term><option>--root-password-file=<replaceable>PATH</replaceable></option></term>
<term><option>--root-password-hashed=<replaceable>HASHED_PASSWORD</replaceable></option></term>
<listitem><para>Sets the password of the system's root user. <listitem><para>Sets the password of the system's root user. This creates a
This creates a
<citerefentry project='die-net'><refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry project='die-net'><refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum></citerefentry>
file. This setting exists in two forms: file. This setting exists in three forms: <option>--root-password=</option> accepts the password to
<option>--root-password=</option> accepts the password to set set directly on the command line, <option>--root-password-file=</option> reads it from a file and
directly on the command line, and <option>--root-password-hashed=</option> accepts an already hashed password on the command line. See
<option>--root-password-file=</option> reads it from a file. <citerefentry project='die-net'><refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum></citerefentry>
Note that it is not recommended to specify passwords on the for more information on the format of the hashed password. Note that it is not recommended to specify
command line, as other users might be able to see them simply plaintext passwords on the command line, as other users might be able to see them simply by invoking
by invoking <citerefentry project='die-net'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
<citerefentry project='die-net'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -53,6 +53,7 @@ static bool arg_copy_timezone = false;
static bool arg_copy_root_password = false; static bool arg_copy_root_password = false;
static bool arg_force = false; static bool arg_force = false;
static bool arg_delete_root_password = false; static bool arg_delete_root_password = false;
static bool arg_root_password_is_hashed = false;
STATIC_DESTRUCTOR_REGISTER(arg_root, freep); STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
STATIC_DESTRUCTOR_REGISTER(arg_locale, freep); STATIC_DESTRUCTOR_REGISTER(arg_locale, freep);
@ -718,7 +719,6 @@ static int write_root_shadow(const char *shadow_path, const char *hashed_passwor
} }
static int process_root_password(void) { static int process_root_password(void) {
_cleanup_free_ char *salt = NULL;
_cleanup_close_ int lock = -1; _cleanup_close_ int lock = -1;
struct crypt_data cd = {}; struct crypt_data cd = {};
const char *hashed_password; const char *hashed_password;
@ -779,6 +779,12 @@ static int process_root_password(void) {
if (!arg_root_password) if (!arg_root_password)
return 0; return 0;
if (arg_root_password_is_hashed)
hashed_password = arg_root_password;
else {
_cleanup_free_ char *salt = NULL;
/* hashed_password points inside cd after crypt_r returns so cd has function scope. */
r = make_salt(&salt); r = make_salt(&salt);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get salt: %m"); return log_error_errno(r, "Failed to get salt: %m");
@ -788,6 +794,7 @@ static int process_root_password(void) {
if (!hashed_password) if (!hashed_password)
return log_error_errno(errno == 0 ? SYNTHETIC_ERRNO(EINVAL) : errno, return log_error_errno(errno == 0 ? SYNTHETIC_ERRNO(EINVAL) : errno,
"Failed to encrypt password: %m"); "Failed to encrypt password: %m");
}
r = write_root_shadow(etc_shadow, hashed_password); r = write_root_shadow(etc_shadow, hashed_password);
if (r < 0) if (r < 0)
@ -816,8 +823,9 @@ static int help(void) {
" --timezone=TIMEZONE Set timezone\n" " --timezone=TIMEZONE Set timezone\n"
" --hostname=NAME Set hostname\n" " --hostname=NAME Set hostname\n"
" --machine-ID=ID Set machine ID\n" " --machine-ID=ID Set machine ID\n"
" --root-password=PASSWORD Set root password\n" " --root-password=PASSWORD Set root password from plaintext password\n"
" --root-password-file=FILE Set root password from file\n" " --root-password-file=FILE Set root password from file\n"
" --root-password-hashed=HASHED_PASSWORD Set root password from hashed password\n"
" --prompt-locale Prompt the user for locale settings\n" " --prompt-locale Prompt the user for locale settings\n"
" --prompt-keymap Prompt the user for keymap settings\n" " --prompt-keymap Prompt the user for keymap settings\n"
" --prompt-timezone Prompt the user for timezone\n" " --prompt-timezone Prompt the user for timezone\n"
@ -853,6 +861,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_MACHINE_ID, ARG_MACHINE_ID,
ARG_ROOT_PASSWORD, ARG_ROOT_PASSWORD,
ARG_ROOT_PASSWORD_FILE, ARG_ROOT_PASSWORD_FILE,
ARG_ROOT_PASSWORD_HASHED,
ARG_PROMPT, ARG_PROMPT,
ARG_PROMPT_LOCALE, ARG_PROMPT_LOCALE,
ARG_PROMPT_KEYMAP, ARG_PROMPT_KEYMAP,
@ -881,6 +890,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "machine-id", required_argument, NULL, ARG_MACHINE_ID }, { "machine-id", required_argument, NULL, ARG_MACHINE_ID },
{ "root-password", required_argument, NULL, ARG_ROOT_PASSWORD }, { "root-password", required_argument, NULL, ARG_ROOT_PASSWORD },
{ "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE }, { "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE },
{ "root-password-hashed", required_argument, NULL, ARG_ROOT_PASSWORD_HASHED },
{ "prompt", no_argument, NULL, ARG_PROMPT }, { "prompt", no_argument, NULL, ARG_PROMPT },
{ "prompt-locale", no_argument, NULL, ARG_PROMPT_LOCALE }, { "prompt-locale", no_argument, NULL, ARG_PROMPT_LOCALE },
{ "prompt-keymap", no_argument, NULL, ARG_PROMPT_KEYMAP }, { "prompt-keymap", no_argument, NULL, ARG_PROMPT_KEYMAP },
@ -959,6 +969,8 @@ static int parse_argv(int argc, char *argv[]) {
r = free_and_strdup(&arg_root_password, optarg); r = free_and_strdup(&arg_root_password, optarg);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
arg_root_password_is_hashed = false;
break; break;
case ARG_ROOT_PASSWORD_FILE: case ARG_ROOT_PASSWORD_FILE:
@ -968,6 +980,15 @@ static int parse_argv(int argc, char *argv[]) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to read %s: %m", optarg); return log_error_errno(r, "Failed to read %s: %m", optarg);
arg_root_password_is_hashed = false;
break;
case ARG_ROOT_PASSWORD_HASHED:
r = free_and_strdup(&arg_root_password, optarg);
if (r < 0)
return log_oom();
arg_root_password_is_hashed = true;
break; break;
case ARG_HOSTNAME: case ARG_HOSTNAME: