Various updates
manage_sudo.sh: moved essential configuration items of the script into a separate configuration file (global/local), fix in wait_for_children (VRF 1.2.0) [Patrick Van der Veken] update_sudo.pl: VRF 1.1.0: replace uname/hostname syscalls, now support for FQDN via $use_fqdn, other fixes [Patrick Van der Veken] Other fixes and cleanups
This commit is contained in:
parent
389aacac9b
commit
7726d1579c
52
manage_sudo.conf
Normal file
52
manage_sudo.conf
Normal file
@ -0,0 +1,52 @@
|
||||
#******************************************************************************
|
||||
# manage_ssh.sh configuration file
|
||||
#******************************************************************************
|
||||
#
|
||||
# Lines starting with '#' (hash) are comment lines
|
||||
#
|
||||
# Format: option=<value>
|
||||
#
|
||||
# Use double or single quotes around the option values in case of strings.
|
||||
#
|
||||
|
||||
# name of the user account performing the SUDO controls copies
|
||||
# (leave blank for current user)
|
||||
SUDO_TRANSFER_USER=""
|
||||
|
||||
# name of the OS group that should own the SUDO controls files
|
||||
SUDO_OWNER_GROUP="sudoadmin"
|
||||
|
||||
# extra arguments/options for the SFTP command
|
||||
SFTP_ARGS="-o StrictHostKeyChecking=no -o ConnectTimeout=10 -b - "
|
||||
|
||||
# extra arguments/options for the SSH command
|
||||
SSH_ARGS="-o StrictHostKeyChecking=no -o ConnectTimeout=10 -n"
|
||||
|
||||
# location of the local SUDO controls directory
|
||||
LOCAL_DIR="/etc/sudo_master"
|
||||
|
||||
# location of the remote SUDO controls directory
|
||||
REMOTE_DIR="/etc/sudo_controls/holding"
|
||||
|
||||
# name of the user account performing the SUDO controls update
|
||||
# (leave blank for current user but user should have remote sudo root privs)
|
||||
SUDO_UPDATE_USER=""
|
||||
|
||||
# options to pass to manage_ssh.sh when executing a key update
|
||||
SUDO_UPDATE_OPTS="--verbose --remove"
|
||||
|
||||
# path to the visudo tool
|
||||
VISUDO_BIN="/usr/sbin/visudo"
|
||||
|
||||
# maximum number of background process to spawn (~maxuprc, ~nstrpty etc)
|
||||
MAX_BACKGROUND_PROCS=30
|
||||
|
||||
# location of the backup directory (for configuration & key files)
|
||||
BACKUP_DIR="${LOCAL_DIR}/backup"
|
||||
|
||||
# location of log directory (default), see --log-dir)
|
||||
LOG_DIR="/var/log"
|
||||
|
||||
#******************************************************************************
|
||||
# End of FILE
|
||||
#******************************************************************************
|
@ -20,10 +20,11 @@
|
||||
# DOES: performs basic functions for SUDO controls: update SUDOers files locally
|
||||
# or remote, validate SUDO syntax, distribute the SUDO fragment files
|
||||
# EXPECTS: (see --help for more options)
|
||||
# REQUIRES: check_config(), check_logging(), check_params(), check_setup(),
|
||||
# check_syntax(), count_fields(), die(), display_usage(),
|
||||
# REQUIRES: check_config(), check_logging(), check_params(), check_root_user(),
|
||||
# check_setup(), check_syntax(), count_fields(), die(), display_usage(),
|
||||
# distribute2host(), do_cleanup(), fix2host(), log(), resolve_host(),
|
||||
# sftp_file(), update2host(), validate_syntax(), warn()
|
||||
# sftp_file(), update2host(), validate_syntax(), wait_for_children(),
|
||||
# warn()
|
||||
# For other pre-requisites see the documentation in display_usage()
|
||||
#
|
||||
# @(#) HISTORY:
|
||||
@ -34,7 +35,9 @@
|
||||
# @(#) 2015-02-02: allow fragments files to have extensions in merge_fragments()
|
||||
# use 'sudo -n' (VRF 1.1.2) [Patrick Van der Veken]
|
||||
# @(#) 2015-04-10: fix in --fix-local routine (VRF 1.1.3) [Patrick Van der Veken]
|
||||
# @(#) 2015-05-16: added SSH_OWNER_GROUP (VRF 1.1.4) [Patrick Van der Veken]
|
||||
# @(#) 2015-08-18: moved essential configuration items of the script into a
|
||||
# @(#) separate configuration file (global/local), fix in
|
||||
# @(#) wait_for_children (VRF 1.2.0) [Patrick Van der Veken]
|
||||
# -----------------------------------------------------------------------------
|
||||
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
|
||||
#******************************************************************************
|
||||
@ -44,32 +47,15 @@
|
||||
#******************************************************************************
|
||||
|
||||
# ------------------------- CONFIGURATION starts here -------------------------
|
||||
# Below configuration values should not be changed. Use the GLOBAL_CONFIG_FILE
|
||||
# or LOCAL_CONFIG_FILE instead
|
||||
|
||||
# define the V.R.F (version/release/fix)
|
||||
MY_VRF="1.1.4"
|
||||
# name of the user account performing the SUDO controls copies
|
||||
# (leave blank for current user)
|
||||
SUDO_TRANSFER_USER=""
|
||||
# name of the OS group that should own the SUDO controls files
|
||||
SUDO_OWNER_GROUP="sudoadmin"
|
||||
# extra arguments/options for the SFTP command
|
||||
SFTP_ARGS="-o StrictHostKeyChecking=no -o ConnectTimeout=10 -b - "
|
||||
# extra arguments/options for the SSH command
|
||||
SSH_ARGS="-o StrictHostKeyChecking=no -o ConnectTimeout=10 -n"
|
||||
# location of the local SUDO controls directory
|
||||
LOCAL_DIR="/etc/sudo_controls"
|
||||
# location of the remote SUDO controls directory
|
||||
REMOTE_DIR="/etc/sudo_controls/holding"
|
||||
# name of the user account performing the SUDO controls update
|
||||
# (leave blank for current user but user should have remote sudo root privs)
|
||||
SUDO_UPDATE_USER=""
|
||||
# path to the visudo tool
|
||||
VISUDO_BIN="/usr/sbin/visudo"
|
||||
# maximum number of background process to spawn (~maxuprc, ~nstrpty etc)
|
||||
MAX_BACKGROUND_PROCS=30
|
||||
# location of the backup directory (for configuration & key files)
|
||||
BACKUP_DIR="${LOCAL_DIR}/backup"
|
||||
# location of log directory (default), see --log-dir)
|
||||
LOG_DIR="/var/log"
|
||||
MY_VRF="1.2.0"
|
||||
# name of the global configuration file (script)
|
||||
GLOBAL_CONFIG_FILE="manage_sudo.conf"
|
||||
# name of the local configuration file (script)
|
||||
LOCAL_CONFIG_FILE="manage_sudonf.local"
|
||||
# location of temporary working storage
|
||||
TMP_DIR="/var/tmp"
|
||||
# ------------------------- CONFIGURATION ends here ---------------------------
|
||||
@ -324,7 +310,8 @@ if (( ARG_ACTION == 1 || ARG_ACTION == 2 || ARG_ACTION == 4 ))
|
||||
then
|
||||
for FILE in "${LOCAL_DIR}/update_sudo.pl" \
|
||||
"${LOCAL_DIR}/update_sudo.conf" \
|
||||
"${SCRIPT_DIR}/${SCRIPT_NAME}"
|
||||
"${SCRIPT_DIR}/${SCRIPT_NAME}" \
|
||||
"${SCRIPT_DIR}/${GLOBAL_CONFIG_FILE}"
|
||||
do
|
||||
if [[ ! -r "${FILE}" ]]
|
||||
then
|
||||
@ -460,6 +447,8 @@ Note 1: distribute and update actions are run in parallel across a maximum of
|
||||
Note 2: make sure correct 'sudo' rules are setup on the target systems to allow
|
||||
the SUDO controls script to run with elevated privileges.
|
||||
|
||||
Note 3: only GLOBAL configuration files will be distributed to target hosts.
|
||||
|
||||
EOT
|
||||
|
||||
return 0
|
||||
@ -486,7 +475,8 @@ for FILE in "${LOCAL_DIR}/grants!660" \
|
||||
"${LOCAL_DIR}/alias!660" \
|
||||
"${LOCAL_DIR}/update_sudo.pl!770" \
|
||||
"${LOCAL_DIR}/update_sudo.conf!660" \
|
||||
"${SCRIPT_DIR}/${SCRIPT_NAME}!770"
|
||||
"${SCRIPT_DIR}/${SCRIPT_NAME}!770" \
|
||||
"${SCRIPT_DIR}/${GLOBAL_CONFIG_FILE}!660"
|
||||
do
|
||||
# sftp transfer
|
||||
sftp_file ${FILE} ${SERVER}
|
||||
@ -515,7 +505,7 @@ then
|
||||
die "failed to merge fragments into the temporary file ${TMP_MERGE_FILE}"
|
||||
fi
|
||||
# sftp transfer
|
||||
sftp_file "${TMP_MERGE_FILE}!440" ${SERVER}
|
||||
sftp_file "${TMP_MERGE_FILE}!640" ${SERVER}
|
||||
COPY_RC=$?
|
||||
if (( ! COPY_RC ))
|
||||
then
|
||||
@ -525,7 +515,7 @@ then
|
||||
fi
|
||||
[[ -d ${TMP_WORK_DIR} ]] && rm -rf ${TMP_WORK_DIR} 2>/dev/null
|
||||
else
|
||||
sftp_file "${FRAGS_FILE}!440" ${SERVER}
|
||||
sftp_file "${FRAGS_FILE}!640" ${SERVER}
|
||||
COPY_RC=$?
|
||||
if (( ! COPY_RC ))
|
||||
then
|
||||
@ -683,7 +673,7 @@ OLD_PWD=$(pwd) && cd ${TRANSFER_DIR}
|
||||
sftp ${SFTP_ARGS} ${SUDO_TRANSFER_USER}@${TRANSFER_HOST} >/dev/null <<EOT
|
||||
cd ${REMOTE_DIR}
|
||||
put ${SOURCE_FILE}
|
||||
#chmod ${TRANSFER_PERMS} ${SOURCE_FILE}
|
||||
chmod ${TRANSFER_PERMS} ${SOURCE_FILE}
|
||||
EOT
|
||||
SFTP_RC=$?
|
||||
|
||||
@ -747,13 +737,13 @@ do
|
||||
# the child might have already ended before we get here (caveat emptor)
|
||||
elif $(wait ${PID})
|
||||
then
|
||||
log "child process ${PID} exited"
|
||||
else
|
||||
log "child process ${PID} exited"
|
||||
log "child process ${PID} exited [NOK]"
|
||||
WAIT_ERRORS=$(( WAIT_ERRORS + 1 ))
|
||||
else
|
||||
log "child process ${PID} exited [OK]"
|
||||
fi
|
||||
done
|
||||
# break loop if we no child PIDs left
|
||||
# break loop if we have no child PIDs left
|
||||
(($# > 0)) || break
|
||||
sleep 1 # required to avoid race conditions
|
||||
done
|
||||
@ -884,6 +874,21 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
# check for configuration files (local overrides local)
|
||||
if [[ -r "${SCRIPT_DIR}/${GLOBAL_CONFIG_FILE}" || -r "${SCRIPT_DIR}/${LOCAL_CONFIG_FILE}" ]]
|
||||
then
|
||||
if [[ -r "${SCRIPT_DIR}/${GLOBAL_CONFIG_FILE}" ]]
|
||||
then
|
||||
. "${SCRIPT_DIR}/${GLOBAL_CONFIG_FILE}"
|
||||
fi
|
||||
if [[ -r "${SCRIPT_DIR}/${LOCAL_CONFIG_FILE}" ]]
|
||||
then
|
||||
. "${SCRIPT_DIR}/${LOCAL_CONFIG_FILE}"
|
||||
fi
|
||||
else
|
||||
print -u2 "ERROR: could not find global or local configuration file"
|
||||
fi
|
||||
|
||||
# startup checks
|
||||
check_params && check_config && check_setup && check_logging
|
||||
|
||||
@ -923,7 +928,7 @@ case ${ARG_ACTION} in
|
||||
then
|
||||
# wait until all background processes are completed
|
||||
wait_for_children ${PIDS} || \
|
||||
warn "$? background jobs failed to complete correctly"
|
||||
warn "$? background jobs (possibly) failed to complete correctly"
|
||||
PIDS=''
|
||||
# reset max updates in background
|
||||
COUNT=${MAX_BACKGROUND_PROCS}
|
||||
@ -931,7 +936,7 @@ case ${ARG_ACTION} in
|
||||
done
|
||||
# final wait for background processes to be finished completely
|
||||
wait_for_children ${PIDS} || \
|
||||
warn "$? background jobs failed to complete correctly"
|
||||
warn "$? background jobs (possibly) failed to complete correctly"
|
||||
|
||||
log "finished applying SUDO controls remotely"
|
||||
;;
|
||||
@ -962,7 +967,7 @@ case ${ARG_ACTION} in
|
||||
then
|
||||
# wait until all background processes are completed
|
||||
wait_for_children ${PIDS} || \
|
||||
warn "$? background jobs failed to complete correctly"
|
||||
warn "$? background jobs (possibly) failed to complete correctly"
|
||||
PIDS=''
|
||||
# reset max updates in background
|
||||
COUNT=${MAX_BACKGROUND_PROCS}
|
||||
@ -970,7 +975,7 @@ case ${ARG_ACTION} in
|
||||
done
|
||||
# final wait for background processes to be finished completely
|
||||
wait_for_children ${PIDS} || \
|
||||
warn "$? background jobs failed to complete correctly"
|
||||
warn "$? background jobs (possibly) failed to complete correctly"
|
||||
log "finished copying/distributing SUDO controls"
|
||||
;;
|
||||
3) # perform syntax checking
|
||||
@ -1012,7 +1017,7 @@ case ${ARG_ACTION} in
|
||||
;;
|
||||
4) # apply SUDO controls locally (root user)
|
||||
log "ACTION: apply SUDO controls locally"
|
||||
log "$(${LOCAL_DIR}/update_sudo.pl -v)"
|
||||
log "$(${LOCAL_DIR}/update_sudo.pl ${SUDO_UPDATE_OPTS})"
|
||||
# no error checking possible here due to log(), done in called script
|
||||
log "finished applying SUDO controls locally"
|
||||
;;
|
||||
@ -1128,7 +1133,7 @@ case ${ARG_ACTION} in
|
||||
then
|
||||
# wait until all background processes are completed
|
||||
wait_for_children ${PIDS} || \
|
||||
warn "$? background jobs failed to complete correctly"
|
||||
warn "$? background jobs (possibly) failed to complete correctly"
|
||||
PIDS=''
|
||||
# reset max updates in background
|
||||
COUNT=${MAX_BACKGROUND_PROCS}
|
||||
@ -1136,11 +1141,11 @@ case ${ARG_ACTION} in
|
||||
done
|
||||
# final wait for background processes to be finished completely
|
||||
wait_for_children ${PIDS} || \
|
||||
warn "$? background jobs failed to complete correctly"
|
||||
warn "$? background jobs (possibly) failed to complete correctly"
|
||||
log "finished applying fixes to the remote SUDO control repository"
|
||||
;;
|
||||
7) # dump the configuration namespace
|
||||
log "ACTION: dumping the global grant namespace with resolved aliases ..."
|
||||
log "ACTION: dumping the global grants namespace with resolved aliases ..."
|
||||
${LOCAL_DIR}/update_sudo.pl --preview --global
|
||||
log "finished dumping the global namespace"
|
||||
;;
|
||||
|
1178
manage_sudo.sh.bak
Normal file
1178
manage_sudo.sh.bak
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,9 @@
|
||||
# Do not use double or single quotes around the option values
|
||||
#
|
||||
|
||||
# use short hostnames or FQDN (0=short names; 1=FQDN) [default: 0]
|
||||
use_fqdn=1
|
||||
|
||||
# target directory for sudo fragment files
|
||||
fragments_dir=/etc/sudo_controls/sudoers.d
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
#******************************************************************************
|
||||
|
||||
use strict;
|
||||
use Net::Domain qw(hostfqdn hostname);
|
||||
use POSIX qw(uname);
|
||||
use Data::Dumper;
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
@ -42,7 +44,7 @@ use File::Temp qw(tempfile);
|
||||
|
||||
# ------------------------- CONFIGURATION starts here -------------------------
|
||||
# define the V.R.F (version/release/fix)
|
||||
my $MY_VRF = "1.0.3";
|
||||
my $MY_VRF = "1.1.0";
|
||||
# name of global configuration file (no path, must be located in the script directory)
|
||||
my $global_config_file = "update_sudo.conf";
|
||||
# name of localized configuration file (no path, must be located in the script directory)
|
||||
@ -51,7 +53,7 @@ my $local_config_file = "update_sudo.conf.local";
|
||||
my $selinux_context = "etc_t";
|
||||
# ------------------------- CONFIGURATION ends here ---------------------------
|
||||
# initialize variables
|
||||
my ($debug, $verbose, $preview, $global) = (0,0,0,0);
|
||||
my ($debug, $verbose, $preview, $global, $use_fqdn) = (0,0,0,0,0);
|
||||
my (@config_files, $fragments_dir, $visudo_bin, $immutable_self_file, $immutable_self_cmd);
|
||||
my (%options, %aliases, %frags, @grants);
|
||||
my ($os, $host, $hostname, $run_dir);
|
||||
@ -85,8 +87,8 @@ sub parse_config_file {
|
||||
my $config_file = shift;
|
||||
|
||||
unless (open (CONF_FD, "<", $config_file)) {
|
||||
do_log ("ERROR: failed to open the configuration file ${config_file} [$! $hostname]") and \
|
||||
exit (1);
|
||||
do_log ("ERROR: failed to open the configuration file ${config_file} [$! $hostname]")
|
||||
and exit (1);
|
||||
}
|
||||
while (<CONF_FD>) {
|
||||
chomp ();
|
||||
@ -94,6 +96,10 @@ sub parse_config_file {
|
||||
if (/^\s*$/ || /^#/) {
|
||||
next;
|
||||
} else {
|
||||
if (/^\s*use_fqdn\s*=\s*([0-9]+)\s*$/) {
|
||||
$use_fqdn = $1;
|
||||
do_log ("DEBUG: picking up setting: use_fqdn=${use_fqdn}");
|
||||
}
|
||||
if (/^\s*fragments_dir\s*=\s*([0-9A-Za-z_\-\.\/~]+)\s*$/) {
|
||||
$fragments_dir = $1;
|
||||
do_log ("DEBUG: picking up setting: fragments_dir=${fragments_dir}");
|
||||
@ -226,12 +232,10 @@ unless ($preview and $global) {
|
||||
}
|
||||
}
|
||||
# where am I?
|
||||
$host = `hostname`;
|
||||
chomp ($host);
|
||||
if ($host =~ /\./) {
|
||||
($hostname) = $host =~ /(.*?)\./;
|
||||
unless ($use_fqdn) {
|
||||
$hostname = hostfqdn();
|
||||
} else {
|
||||
$hostname = $host;
|
||||
$hostname = hostname();
|
||||
}
|
||||
$0 =~ /^(.+[\\\/])[^\\\/]+[\\\/]*$/;
|
||||
my $run_dir = $1 || ".";
|
||||
@ -733,3 +737,4 @@ S< >Show version of the script.
|
||||
@(#) 2014-12-16: VRF 1.0.1: added SELinux context [Patrick Van der Veken]
|
||||
@(#) 2014-12-16: VRF 1.0.2: fixed a problem with the immutable self fragment code [Patrick Van der Veken]
|
||||
@(#) 2015-02-02: VRF 1.0.3: changed 'basename' into 'fileparse' call to support fragment files with extensions [Patrick Van der Veken]
|
||||
@(#) 2015-08-18: VRF 1.1.0: replace uname/hostname syscalls, now support for FQDN via $use_fqdn, other fixes [Patrick Van der Veken]
|
Loading…
x
Reference in New Issue
Block a user