From 32d6bc6ad1f5d857c8e34e15001f8eb8666c601c Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Sun, 29 Mar 2015 14:16:44 -0500 Subject: [PATCH] Add inc/rootwrap Rootwrap shouldn't be a unique snowflake. Plus the binaries tend to be called assuming PATH will find them. Not so with venvs so we need to work around that brokenness. Configure Cinder and Nova to use configure_rootwrap(). Change-Id: I8ee1f66014875caf20a2d14ff6ef3672673ba85a --- functions | 1 + inc/rootwrap | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/cinder | 38 +------------------------- lib/nova | 38 +------------------------- 4 files changed, 80 insertions(+), 74 deletions(-) create mode 100644 inc/rootwrap diff --git a/functions b/functions index 5bc8456281..4dc20e7f23 100644 --- a/functions +++ b/functions @@ -15,6 +15,7 @@ FUNC_DIR=$(cd $(dirname "${BASH_SOURCE:-$0}") && pwd) source ${FUNC_DIR}/functions-common source ${FUNC_DIR}/inc/ini-config source ${FUNC_DIR}/inc/python +source ${FUNC_DIR}/inc/rootwrap # Save trace setting XTRACE=$(set +o | grep xtrace) diff --git a/inc/rootwrap b/inc/rootwrap new file mode 100644 index 0000000000..bac8e1e86c --- /dev/null +++ b/inc/rootwrap @@ -0,0 +1,77 @@ +#!/bin/bash +# +# **inc/rootwrap** - Rootwrap functions +# +# Handle rootwrap's foibles + +# Uses: ``STACK_USER`` +# Defines: ``SUDO_SECURE_PATH_FILE`` + +# Save trace setting +INC_ROOT_TRACE=$(set +o | grep xtrace) +set +o xtrace + +# Accumulate all additions to sudo's ``secure_path`` in one file read last +# so they all work in a venv configuration +SUDO_SECURE_PATH_FILE=${SUDO_SECURE_PATH_FILE:-/etc/sudoers.d/zz-secure-path} + +# Add a directory to the common sudo ``secure_path`` +# add_sudo_secure_path dir +function add_sudo_secure_path { + local dir=$1 + local line + + # This is pretty simplistic for now - assume only the first line is used + if [[ -r SUDO_SECURE_PATH_FILE ]]; then + line=$(head -1 $SUDO_SECURE_PATH_FILE) + else + line="Defaults:$STACK_USER secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin" + fi + + # Only add ``dir`` if it is not already present + if [[ $line =~ $dir ]]; then + echo "${line}:$dir" | sudo tee $SUDO_SECURE_PATH_FILE + sudo chmod 400 $SUDO_SECURE_PATH_FILE + sudo chown root:root $SUDO_SECURE_PATH_FILE + fi +} + +# Configure rootwrap +# Make a load of assumptions otherwise we'll have 6 arguments +# configure_rootwrap project bin conf-src-dir +function configure_rootwrap { + local project=$1 # xx + local rootwrap_bin=$2 # /opt/stack/xx.venv/bin/xx-rootwrap + local rootwrap_conf_src_dir=$3 # /opt/stack/xx/etc/xx + + # Start fresh with rootwrap filters + sudo rm -rf /etc/${project}/rootwrap.d + sudo install -d -o root -g root -m 755 /etc/${project}/rootwrap.d + sudo install -o root -g root -m 644 $rootwrap_conf_src_dir/rootwrap.d/*.filters /etc/${project}/rootwrap.d + + # Set up rootwrap.conf, pointing to /etc/*/rootwrap.d + sudo install -o root -g root -m 644 $rootwrap_conf_src_dir/rootwrap.conf /etc/${project}/rootwrap.conf + sudo sed -e "s:^filters_path=.*$:filters_path=/etc/${project}/rootwrap.d:" -i /etc/${project}/rootwrap.conf + + # Specify rootwrap.conf as first parameter to rootwrap + rootwrap_sudo_cmd="$rootwrap_bin /etc/${project}/rootwrap.conf *" + + # Set up the rootwrap sudoers + local tempfile=$(mktemp) + echo "$STACK_USER ALL=(root) NOPASSWD: $rootwrap_sudo_cmd" >$tempfile + chmod 0440 $tempfile + sudo chown root:root $tempfile + sudo mv $tempfile /etc/sudoers.d/${project}-rootwrap + + # Add bin dir to sudo's secure_path because rootwrap is being called + # without a path because BROKEN. + add_sudo_secure_path $(dirname $rootwrap_bin) +} + + +# Restore xtrace +$INC_ROOT_TRACE + +# Local variables: +# mode: shell-script +# End: diff --git a/lib/cinder b/lib/cinder index 27fd692292..de41bc5f79 100644 --- a/lib/cinder +++ b/lib/cinder @@ -171,42 +171,6 @@ function cleanup_cinder { fi } -# Deploy new rootwrap filters files and configure sudo -# configure_cinder_rootwrap() - configure Cinder's rootwrap -function configure_cinder_rootwrap { - local cinder_rootwrap=$CINDER_BIN_DIR/cinder-rootwrap - - # Wipe any existing rootwrap.d files first - if [[ -d $CINDER_CONF_DIR/rootwrap.d ]]; then - sudo rm -rf $CINDER_CONF_DIR/rootwrap.d - fi - - # Deploy filters to /etc/cinder/rootwrap.d - sudo install -d -o root -g root -m 755 $CINDER_CONF_DIR/rootwrap.d - sudo install -o root -g root -m 644 $CINDER_DIR/etc/cinder/rootwrap.d/*.filters $CINDER_CONF_DIR/rootwrap.d - - # Set up rootwrap.conf, pointing to /etc/cinder/rootwrap.d - sudo install -o root -g root -m 644 $CINDER_DIR/etc/cinder/rootwrap.conf $CINDER_CONF_DIR - sudo sed -e "s:^filters_path=.*$:filters_path=$CINDER_CONF_DIR/rootwrap.d:" -i $CINDER_CONF_DIR/rootwrap.conf - - # Specify rootwrap.conf as first parameter to rootwrap - ROOTWRAP_CSUDOER_CMD="$cinder_rootwrap $CINDER_CONF_DIR/rootwrap.conf *" - - # Set up the rootwrap sudoers for cinder - local tempfile=`mktemp` - echo "Defaults:$STACK_USER secure_path=$CINDER_BIN_DIR:/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >$tempfile - echo "$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_CSUDOER_CMD" >>$tempfile - chmod 0440 $tempfile - sudo chown root:root $tempfile - sudo mv $tempfile /etc/sudoers.d/cinder-rootwrap - - # So rootwrap and PATH are broken beyond belief. WTF relies on a SECURE operation - # to blindly follow PATH??? We learned that was a bad idea in the 80's! - # So to fix this in a venv, we must exploit the very hole we want to close by dropping - # a copy of the venv rootwrap binary into /usr/local/bin. - #sudo cp -p $cinder_rootwrap /usr/local/bin -} - # configure_cinder() - Set config files, create data dirs, etc function configure_cinder { sudo install -d -o $STACK_USER -m 755 $CINDER_CONF_DIR @@ -215,7 +179,7 @@ function configure_cinder { rm -f $CINDER_CONF - configure_cinder_rootwrap + configure_rootwrap cinder $CINDER_BIN_DIR/cinder-rootwrap $CINDER_DIR/etc/cinder cp $CINDER_DIR/etc/cinder/api-paste.ini $CINDER_API_PASTE_INI diff --git a/lib/nova b/lib/nova index 385da4e44b..807dfceeae 100644 --- a/lib/nova +++ b/lib/nova @@ -223,42 +223,6 @@ function cleanup_nova { #fi } -# Deploy new rootwrap filters files and configure sudo -# configure_nova_rootwrap() - configure Nova's rootwrap -function configure_nova_rootwrap { - nova_rootwrap=$NOVA_BIN_DIR/nova-rootwrap - - # Wipe any existing rootwrap.d files first - if [[ -d $NOVA_CONF_DIR/rootwrap.d ]]; then - sudo rm -rf $NOVA_CONF_DIR/rootwrap.d - fi - - # Deploy filters to /etc/nova/rootwrap.d - sudo install -d -o root -g root -m 755 $NOVA_CONF_DIR/rootwrap.d - sudo install -o root -g root -m 644 $NOVA_DIR/etc/nova/rootwrap.d/*.filters $NOVA_CONF_DIR/rootwrap.d - - # Set up rootwrap.conf, pointing to /etc/nova/rootwrap.d - sudo install -o root -g root -m 644 $NOVA_DIR/etc/nova/rootwrap.conf $NOVA_CONF_DIR - sudo sed -e "s:^filters_path=.*$:filters_path=$NOVA_CONF_DIR/rootwrap.d:" -i $NOVA_CONF_DIR/rootwrap.conf - - # Specify rootwrap.conf as first parameter to nova-rootwrap - local rootwrap_sudoer_cmd="$nova_rootwrap $NOVA_CONF_DIR/rootwrap.conf *" - - # Set up the rootwrap sudoers for nova - local tempfile=`mktemp` - echo "Defaults:$STACK_USER secure_path=$NOVA_BIN_DIR:/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >$tempfile - echo "$STACK_USER ALL=(root) NOPASSWD: $rootwrap_sudoer_cmd" >>$tempfile - chmod 0440 $tempfile - sudo chown root:root $tempfile - sudo mv $tempfile /etc/sudoers.d/nova-rootwrap - - # So rootwrap and PATH are broken beyond belief. WTF relies on a SECURE operation - # to blindly follow PATH??? We learned that was a bad idea in the 80's! - # So to fix this in a venv, we must exploit the very hole we want to close by dropping - # a copy of the venv rootwrap binary into /usr/local/bin. - #sudo cp -p $nova_rootwrap /usr/local/bin -} - # configure_nova() - Set config files, create data dirs, etc function configure_nova { # Put config files in ``/etc/nova`` for everyone to find @@ -266,7 +230,7 @@ function configure_nova { install_default_policy nova - configure_nova_rootwrap + configure_rootwrap nova $NOVA_BIN_DIR/nova-rootwrap $NOVA_DIR/etc/nova if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then # Get the sample configuration file in place