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
This commit is contained in:
Dean Troyer 2015-03-29 14:16:44 -05:00
parent 43479db910
commit 32d6bc6ad1
4 changed files with 80 additions and 74 deletions

View File

@ -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)

77
inc/rootwrap Normal file
View File

@ -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:

View File

@ -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

View File

@ -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