firstboot: Add --delete-root-password option
This commit is contained in:
parent
b4909a3fd0
commit
4926ceaff3
|
@ -230,6 +230,14 @@
|
||||||
<literal>root</literal> user instead of overwriting the entire file.</para></listitem>
|
<literal>root</literal> user instead of overwriting the entire file.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--delete-root-password</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Removes the password of the system's root user, enabling login as root without a
|
||||||
|
password unless the root account is locked. Note that this is extremely insecure and hence this
|
||||||
|
option should not be used lightly.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<xi:include href="standard-options.xml" xpointer="help" />
|
<xi:include href="standard-options.xml" xpointer="help" />
|
||||||
<xi:include href="standard-options.xml" xpointer="version" />
|
<xi:include href="standard-options.xml" xpointer="version" />
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
|
@ -52,6 +52,7 @@ static bool arg_copy_keymap = false;
|
||||||
static bool arg_copy_timezone = false;
|
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_DESTRUCTOR_REGISTER(arg_root, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_locale, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_locale, freep);
|
||||||
|
@ -586,6 +587,69 @@ static int prompt_root_password(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int write_root_passwd(const char *passwd_path, const char *password) {
|
||||||
|
_cleanup_fclose_ FILE *original = NULL, *passwd = NULL;
|
||||||
|
_cleanup_(unlink_and_freep) char *passwd_tmp = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = fopen_temporary_label("/etc/passwd", passwd_path, &passwd, &passwd_tmp);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
original = fopen(passwd_path, "re");
|
||||||
|
if (original) {
|
||||||
|
struct passwd *i;
|
||||||
|
|
||||||
|
r = sync_rights(fileno(original), fileno(passwd));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
while ((r = fgetpwent_sane(original, &i)) > 0) {
|
||||||
|
|
||||||
|
if (streq(i->pw_name, "root"))
|
||||||
|
i->pw_passwd = (char *) password;
|
||||||
|
|
||||||
|
r = putpwent_sane(i, passwd);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
struct passwd root = {
|
||||||
|
.pw_name = (char *) "root",
|
||||||
|
.pw_passwd = (char *) password,
|
||||||
|
.pw_uid = 0,
|
||||||
|
.pw_gid = 0,
|
||||||
|
.pw_gecos = (char *) "Super User",
|
||||||
|
.pw_dir = (char *) "/root",
|
||||||
|
.pw_shell = (char *) "/bin/sh",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (errno != ENOENT)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
r = fchmod(fileno(passwd), 0000);
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
r = putpwent_sane(&root, passwd);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = fflush_sync_and_check(passwd);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = rename_and_apply_smack_floor_label(passwd_tmp, passwd_path);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int write_root_shadow(const char *shadow_path, const char *hashed_password) {
|
static int write_root_shadow(const char *shadow_path, const char *hashed_password) {
|
||||||
_cleanup_fclose_ FILE *original = NULL, *shadow = NULL;
|
_cleanup_fclose_ FILE *original = NULL, *shadow = NULL;
|
||||||
_cleanup_(unlink_and_freep) char *shadow_tmp = NULL;
|
_cleanup_(unlink_and_freep) char *shadow_tmp = NULL;
|
||||||
|
@ -671,6 +735,21 @@ static int process_root_password(void) {
|
||||||
if (lock < 0)
|
if (lock < 0)
|
||||||
return log_error_errno(lock, "Failed to take a lock: %m");
|
return log_error_errno(lock, "Failed to take a lock: %m");
|
||||||
|
|
||||||
|
if (arg_delete_root_password) {
|
||||||
|
const char *etc_passwd;
|
||||||
|
|
||||||
|
/* Mixing alloca() and other stuff that touches the stack in one expression is not portable. */
|
||||||
|
etc_passwd = prefix_roota(arg_root, "/etc/passwd");
|
||||||
|
|
||||||
|
r = write_root_passwd(etc_passwd, "");
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to write %s: %m", etc_passwd);
|
||||||
|
|
||||||
|
log_info("%s written", etc_passwd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (arg_copy_root_password && arg_root) {
|
if (arg_copy_root_password && arg_root) {
|
||||||
struct spwd *p;
|
struct spwd *p;
|
||||||
|
|
||||||
|
@ -752,6 +831,7 @@ static int help(void) {
|
||||||
" --copy Copy locale, keymap, timezone, root password\n"
|
" --copy Copy locale, keymap, timezone, root password\n"
|
||||||
" --setup-machine-id Generate a new random machine ID\n"
|
" --setup-machine-id Generate a new random machine ID\n"
|
||||||
" --force Overwrite existing files\n"
|
" --force Overwrite existing files\n"
|
||||||
|
" --delete-root-password Delete root password\n"
|
||||||
"\nSee the %s for details.\n"
|
"\nSee the %s for details.\n"
|
||||||
, program_invocation_short_name
|
, program_invocation_short_name
|
||||||
, link
|
, link
|
||||||
|
@ -786,6 +866,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
ARG_COPY_ROOT_PASSWORD,
|
ARG_COPY_ROOT_PASSWORD,
|
||||||
ARG_SETUP_MACHINE_ID,
|
ARG_SETUP_MACHINE_ID,
|
||||||
ARG_FORCE,
|
ARG_FORCE,
|
||||||
|
ARG_DELETE_ROOT_PASSWORD,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
|
@ -813,6 +894,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
{ "copy-root-password", no_argument, NULL, ARG_COPY_ROOT_PASSWORD },
|
{ "copy-root-password", no_argument, NULL, ARG_COPY_ROOT_PASSWORD },
|
||||||
{ "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID },
|
{ "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID },
|
||||||
{ "force", no_argument, NULL, ARG_FORCE },
|
{ "force", no_argument, NULL, ARG_FORCE },
|
||||||
|
{ "delete-root-password", no_argument, NULL, ARG_DELETE_ROOT_PASSWORD },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -963,6 +1045,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
arg_force = true;
|
arg_force = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_DELETE_ROOT_PASSWORD:
|
||||||
|
arg_delete_root_password = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -978,6 +1064,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
if (arg_locale_messages && !locale_is_ok(arg_locale_messages))
|
if (arg_locale_messages && !locale_is_ok(arg_locale_messages))
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale %s is not installed.", arg_locale_messages);
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale %s is not installed.", arg_locale_messages);
|
||||||
|
|
||||||
|
if (arg_delete_root_password && (arg_copy_root_password || arg_root_password || arg_prompt_root_password))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"--delete-root-password cannot be combined with other root password options");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue