#!/bin/sh set -e CONF_PATH="/etc/security/rootasrole.json" POLICY_FOLDER="/etc/security/rootasrole.d" POLICY_PATH="$POLICY_FOLDER/default.json" DEFAULT_CONF_PATH="/usr/share/rootasrole/rootasrole.json" DEFAULT_POLICY_PATH="/usr/share/rootasrole/default.json" PACKAGE_VERSION="4.1.0" log() { echo "RootAsRole: $1" >&2 } is_immutable_supported() { FS_TYPE=$(df -T "$1" 2>/dev/null | awk 'NR==2 {print $2}') case "$FS_TYPE" in ext2 | ext3 | ext4 | xfs | btrfs | ocfs2 | jfs | reiserfs) return 0 ;; *) return 1 ;; esac } enable_immutable() { if ! grep -q '"immutable": true' "$CONF_PATH" 2>/dev/null; then sed -i 's/"immutable": false/"immutable": true/' "$CONF_PATH" 2>/dev/null || true fi } disable_immutable() { chattr -i "$CONF_PATH" 2>/dev/null || true for file in "$POLICY_FOLDER"/*; do chattr -i "$file" 2>/dev/null || true done chattr -i "$POLICY_FOLDER" 2>/dev/null || true sed -i 's/"immutable": true/"immutable": false/' "$CONF_PATH" 2>/dev/null || true sed -i "s;\"CAP_LINUX_IMMUTABLE\";;g" "$POLICY_PATH" 2>/dev/null || true } check_immutable() { if ! is_immutable_supported "$1"; then log "The file system used at $1 does not support the immutable flag." return 1 fi if ! chattr +i "$1" >/dev/null 2>&1; then log "Failed to set the immutable flag on $1." return 1 fi } flag_policy() { check_immutable "$CONF_PATH" || return 1 for file in "$POLICY_FOLDER"/*; do [ -f "$file" ] || continue check_immutable "$file" || return 1 done # the folder last: once it is immutable, no policy file can be added or replaced check_immutable "$POLICY_FOLDER" } get_invoking_user() { current_user=$(id -un 2>/dev/null || true) if [ -n "$current_user" ] && [ "$current_user" != "root" ] && [ "$current_user" != "0" ]; then echo "$current_user" return elif [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != "root" ]; then echo "$SUDO_USER" return elif [ -n "$USER" ] && [ "$USER" != "root" ]; then echo "$USER" return elif [ -n "$LOGNAME" ] && [ "$LOGNAME" != "root" ]; then echo "$LOGNAME" return elif [ -n "$USERNAME" ] && [ "$USERNAME" != "root" ]; then echo "$USERNAME" return fi pid=$PPID while [ "$pid" -gt 1 ]; do if ps_output=$(ps -o uid=,user= -p "$pid" 2>/dev/null); then uid=$(echo "$ps_output" | awk '{print $1}') user=$(echo "$ps_output" | awk '{print $2}') if [ "$uid" != "0" ] && [ -n "$uid" ]; then if [ -n "$user" ]; then echo "$user" else echo "$uid" fi return fi fi pid=$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d ' ') || break done echo "root" } setadmin() { TARGET_PATH="$1" if [ -f "$TARGET_PATH" ] && grep -q '"ROOTADMINISTRATOR"' "$TARGET_PATH"; then ADMIN_USER=$(get_invoking_user) echo "Setting the administrator user in $TARGET_PATH to $ADMIN_USER" sed -i -e "s/\"ROOTADMINISTRATOR\"/\"$ADMIN_USER\"/g" \ "$TARGET_PATH" log "The user $ADMIN_USER is now the administrator." fi } configure() { if ! mkdir -p "$(dirname "$CONF_PATH")"; then log "Failed to create the configuration directory." return 1 fi if [ ! -f "$CONF_PATH" ]; then if ! install -m 0600 "$DEFAULT_CONF_PATH" "$CONF_PATH"; then log "Failed to create the default configuration file at $CONF_PATH" return 1 fi fi if ! mkdir -p "$POLICY_FOLDER"; then log "Failed to create the policy folder at $POLICY_FOLDER" return 1 fi if [ ! -f "$POLICY_PATH" ]; then if ! install -m 0600 "$DEFAULT_POLICY_PATH" "$POLICY_PATH"; then log "Failed to copy the default policy to $POLICY_PATH" return 1 fi fi setadmin "$POLICY_PATH" # prerm removed the flags: migrate files written by older versions first if [ -n "$old_version" ]; then chsr upgrade || log "chsr upgrade failed, run it before using dosr" fi enable_immutable flag_policy || disable_immutable } case "$1" in configure | abort-remove | abort-deconfigure) configure setcap '=p' /usr/lib/cargo/bin/dosr 2>/dev/null || log "Failed to set capabilities on /usr/lib/cargo/bin/dosr" ;; abort-upgrade | upgrade | disappear) exit 0 ;; *) log "postinst called with unknown argument \`$1'" exit 1 ;; esac