From 7c3738d06782f39a2f462c4074c75827787eb111 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Wed, 15 Mar 2023 17:19:18 -0500 Subject: [PATCH] Add set-root-password command The `set-root-password` command sets up an alternate mount namespace with a writable `/etc` directory and then runs `passwd` in it. This allows `passwd` to create its lock files and backup files, without requiring that the real `/etc` to be mutable. After `passwd` finishes and has updated its private copy of `/etc/shadow`, the script rewrites the real one with its contents. --- overlay/usr/bin/set-root-password | 56 ++++++++++++ .../selinux-aimee-os/files/aimee-os.fc | 1 + .../selinux-aimee-os/files/aimee-os.if | 88 +++++++++++++++++++ .../selinux-aimee-os/files/aimee-os.te | 65 ++++++++++++++ 4 files changed, 210 insertions(+) create mode 100755 overlay/usr/bin/set-root-password diff --git a/overlay/usr/bin/set-root-password b/overlay/usr/bin/set-root-password new file mode 100755 index 0000000..c26a8bd --- /dev/null +++ b/overlay/usr/bin/set-root-password @@ -0,0 +1,56 @@ +#!/bin/sh +# vim: set sw=4 ts=4 sts=4 et : + +if [ -z "${_UNSHARED}" ]; then + export _UNSHARED=1 + exec unshare -m "$0" "$@" +fi +unset _UNSHARED + +cleanup() { + if is_mount -q /etc; then + umount -R /etc + fi + if [ -n "${tmpdir}" ] && [ "${tmpdir}" != / ]; then + if is_mount "${tmpdir}"; then + umount -R "${tmpdir}" + fi + rm -rf "${tmpdir}" + fi + unset tmpdir +} + +is_mount() { + awk ' + BEGIN { rc = 1 } + $5 == "'"${1}"'" { rc = 0 } + END { exit rc } + ' /proc/self/mountinfo +} + +tmpdir=$(mktemp -d) +trap 'cleanup' INT QUIT TERM EXIT +mount \ + -t tmpfs \ + -o private,rootcontext=system_u:object_r:etc_t:s0 \ + tmpfs \ + "${tmpdir}" \ + || exit + +mkdir -p \ + "${tmpdir}"/etc \ + "${tmpdir}"/etc/pam.d \ + "${tmpdir}"/etc/security \ + "${tmpdir}"/etc/selinux \ + || exit +cp -a /etc/passwd /etc/shadow "${tmpdir}"/etc || exit +mount -o bind /etc/pam.d "${tmpdir}"/etc/pam.d || exit +mount -o bind /etc/security "${tmpdir}"/etc/security || exit +mount -o bind /etc/selinux "${tmpdir}"/etc/selinux || exit +mount --rbind "${tmpdir}"/etc /etc || exit + +passwd || exit + +mv /etc/shadow "${tmpdir}"/shadow || exit +umount -R /etc || exit +cat "${tmpdir}"/shadow > /etc/shadow || exit diff --git a/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.fc b/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.fc index 85a4fab..45fee53 100644 --- a/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.fc +++ b/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.fc @@ -1,4 +1,5 @@ /usr/bin/system-update -- gen_context(system_u:object_r:aimee_sysupdate_exec_t,s0) +/usr/bin/set-root-password -- gen_context(system_u:object_r:aimee_set_root_password_exec_t,s0) /usr/libexec/factory-reset -- gen_context(system_u:object_r:aimee_factory_reset_exec_t,s0) /usr/libexec/init-storage -- gen_context(system_u:object_r:aimee_storinit_exec_t,s0) diff --git a/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.if b/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.if index 4bcb069..8884541 100644 --- a/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.if +++ b/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.if @@ -45,3 +45,91 @@ interface(`aimee_os_run_system_update',` aimee_os_system_update_domtrans($1) role $2 types aimee_sysupdate_t; ') + +######################################## +## +## Execute set-root-password in the +## aimee_set_root_password_t domain. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`aimee_os_set_root_password_domtrans',` + gen_require(` + type aimee_set_root_password_t, aimee_set_root_password_exec_t; + ') + + domtrans_pattern($1, aimee_set_root_password_exec_t, aimee_set_root_password_t) +') + +######################################## +## +## Execute set-root-password in the +## aimee_set_root_password_t domain, and +## allow the specified role the +## aimee_set_root_password_t domain. +## +## +## +## Domain allowed to transition. +## +## +## +## +## Role allowed access. +## +## +## +# +interface(`aimee_os_run_set_root_password',` + gen_require(` + type aimee_set_root_password_t; + ') + + aimee_os_set_root_password_domtrans($1) + role $2 types aimee_set_root_password_t; + mount_run(aimee_set_root_password_t, $2) +') + +######################################## +## +## Execute set-root-password in the caller +## domain. +## +## +## +## Domain allowed access. +## +## +# +interface(`aimee_os_set_root_password_exec',` + gen_require(` + type aimee_set_root_password_exec_t; + ') + + corecmd_search_bin($1) + can_exec($1, aimee_set_root_password_exec_t) +') + +######################################## +## +## Create, read, write, and delete temporary +## files used by Aimee OS set-root-password. +## +## +## +## Domain allowed access. +## +## +# +interface(`aimee_os_manage_set_root_password_tmp_files',` + gen_require(` + type aimee_set_root_password_tmp_t; + ') + + manage_files_pattern($1, aimee_set_root_password_tmp_t, aimee_set_root_password_tmp_t) + read_lnk_files_pattern($1, aimee_set_root_password_tmp_t, aimee_set_root_password_tmp_t) +') diff --git a/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.te b/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.te index eeaa03d..6f16f7d 100644 --- a/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.te +++ b/repos/aimee-os/sec-policy/selinux-aimee-os/files/aimee-os.te @@ -23,6 +23,13 @@ type aimee_factory_reset_t; type aimee_factory_reset_exec_t; init_daemon_domain(aimee_factory_reset_t, aimee_factory_reset_exec_t) +type aimee_set_root_password_t; +type aimee_set_root_password_exec_t; +userdom_user_application_domain(aimee_set_root_password_t, aimee_set_root_password_exec_t) + +type aimee_set_root_password_tmp_t; +files_tmp_file(aimee_set_root_password_tmp_t) + ######################################## # # init-storage local policy @@ -198,6 +205,64 @@ fstools_manage_runtime_files(aimee_factory_reset_t) miscfiles_read_localization(aimee_factory_reset_t) storage_raw_rw_fixed_disk(aimee_factory_reset_t) +######################################## +# +# set-root-password local policy +# + +gen_require(` + class passwd { passwd }; +') + +allow aimee_set_root_password_t self:capability { sys_admin }; +allow aimee_set_root_password_t self:fifo_file rw_fifo_file_perms; +allow aimee_set_root_password_t self:process setfscreate; +allow aimee_set_root_password_t self:process { ptrace sigkill sigstop signal }; +allow aimee_set_root_password_t self:passwd passwd; + +files_tmp_filetrans(aimee_set_root_password_t, aimee_set_root_password_tmp_t, dir) +manage_dirs_pattern(aimee_set_root_password_t, aimee_set_root_password_tmp_t, aimee_set_root_password_tmp_t) +manage_files_pattern(aimee_set_root_password_t, aimee_set_root_password_tmp_t, aimee_set_root_password_tmp_t) +relabel_files_pattern(aimee_set_root_password_t, aimee_set_root_password_tmp_t, aimee_set_root_password_tmp_t) + +domain_use_interactive_fds(aimee_set_root_password_t) +userdom_use_inherited_user_terminals(aimee_set_root_password_t) +userdom_search_user_home_dirs(aimee_set_root_password_t) +corecmd_exec_bin(aimee_set_root_password_t) +selinux_get_fs_mount(aimee_set_root_password_t) +seutil_read_config(aimee_set_root_password_t) +miscfiles_read_localization(aimee_set_root_password_t) +files_mounton_root(aimee_set_root_password_t) +aimee_os_set_root_password_exec(aimee_set_root_password_t) +mount_list_runtime(aimee_set_root_password_t) +fs_getattr_all_fs(aimee_set_root_password_t) +fs_mount_all_fs(aimee_set_root_password_t) +fs_unmount_all_fs(aimee_set_root_password_t) +files_read_var_lib_files(aimee_set_root_password_t) +files_manage_etc_files(aimee_set_root_password_t) +files_relabel_etc_files(aimee_set_root_password_t) +files_manage_etc_dirs(aimee_set_root_password_t) +auth_manage_shadow(aimee_set_root_password_t) +auth_relabel_shadow(aimee_set_root_password_t) +files_mounton_etc_dirs(aimee_set_root_password_t) +usermanage_domtrans_passwd(aimee_set_root_password_t) +dev_read_sysfs(aimee_set_root_password_t) +aimee_os_manage_set_root_password_tmp_files(aimee_set_root_password_t) + +gen_require(` + type mount_t; + type passwd_t; +') +allow aimee_set_root_password_t aimee_set_root_password_tmp_t:dir mounton; +allow mount_t aimee_set_root_password_tmp_t:dir mounton; +aimee_os_manage_set_root_password_tmp_files(passwd_t) + +gen_require(` + type sysadm_t; + role sysadm_r; +') +aimee_os_run_set_root_password(sysadm_t, sysadm_r) + ######################################## # # Additional policy rules for Aimee OS-specific behavior