#!/bin/bash## Name: loginaccounts.sh# Description: automate login account management## Author: Dominick Grift <domg472 at gmail dot com># Version: 0.0.2# Copyright (C) 2008 Dominick Grift# This program is free software: you can redistribute it and/or modify# it under the terms of the GNU Affero General Public License as# published by the Free Software Foundation, either version 3 of the# License, or (at your option) any later version.# This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU Affero General Public License for more details.# You should have received a copy of the GNU Affero General Public License# along with this program. If not, see <http://www.gnu.org/licenses/>.# Report undefined variables# shopt -s -o nounset# Global declarationsdeclare -rx SCRIPT=${0##*/}declare -rx EXITSTATUS=$?# My global declarationsdeclare -r OPTSTRING="-h,-L,-f,-i:,-p:,-c:,-g:,-l:,-n:,-c:,-q:,-e:"declare UCOMMNT=0 # Optionaldeclare UGRP="realusers,sshusers" # Tunabledeclare USERIDdeclare RESULTdeclare UPASSWDdeclare ULOGNS=3 # Tunabledeclare UNPROC=15 # Tunabledeclare ULOCL=0 # Optionaldeclare UCATGR=0 # Optionaldeclare UFORWRD=0 # optionaldeclare UQUOT="10000" # Tunabledeclare UEXPR=0 # Optional# Sanity checks# Requires BASHif test -z "$BASH" ; then printf "$SCRIPT:$LINENO: %s\n" "Please run this script with the BASH shell" >&2 exit 192fi# Test for input# TODO: implement interactive modeif test -z "$1" ; then printf "$SCRIPT:$LINENO: %s\n" "Copyright (C) 2008 Dominick Grift" printf "$SCRIPT:$LINENO: %s\n" "" printf "$SCRIPT:$LINENO: %s\n" "This program is free software: you can redistribute it and/or modify" printf "$SCRIPT:$LINENO: %s\n" "it under the terms of the GNU Affero General Public License as" printf "$SCRIPT:$LINENO: %s\n" "published by the Free Software Foundation, either version 3 of the" printf "$SCRIPT:$LINENO: %s\n" "License, or (at your option) any later version." printf "$SCRIPT:$LINENO: %s\n" "" printf "$SCRIPT:$LINENO: %s\n" "This program is distributed in the hope that it will be useful," printf "$SCRIPT:$LINENO: %s\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of" printf "$SCRIPT:$LINENO: %s\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" printf "$SCRIPT:$LINENO: %s\n" "GNU Affero General Public License for more details." printf "$SCRIPT:$LINENO: %s\n" "" printf "$SCRIPT:$LINENO: %s\n" "You should have received a copy of the GNU Affero General Public License" printf "$SCRIPT:$LINENO: %s\n" "along with this program. If not, see <http://www.gnu.org/licenses/>." exit 0fi# Test for rootif [ `whoami` != "root" ] ; then printf "$SCRIPT:$LINENO: %s\n" "DAC: Must be root" >&2 exit 192fi# Test for unconfinedif [ `id -Z | awk 'BEGIN { FS=":" } { print $3 }'` != unconfined_t ] ; then printf "$SCRIPT:$LINENO: %s\n" "MAC: Must be unconfined domain" >&2 exit 192fi# Check getopt modegetopt -Tif [ $? -ne 4 ] ; then printf "$SCRIPT: %s\n" "Getopt is in compatibility mode" >&2 exit 192fi# Test parametersRESULT='getopt --name "$SCRIPT" --options "$OPTSTRING" --longoptions "help" "identity" "password" "comment" "groups" "logins" "nproc" "local" "range" "forward" "quota" "expire" -- "$@"'if [ $? -gt 0 ] ; then exit 192fi# Functionsfunction add_user { /usr/sbin/useradd $USERID 1>&2 >/dev/null;}function add_user_passwd { /bin/echo $UPASSWD | /usr/bin/passwd $USERID --stdin 1>&2 >/dev/null;}function add_comment { /usr/sbin/usermod -c $UCOMMNT $USERID 1>&2 >/dev/null;}function add_expire { /usr/sbin/usermod -e $UEXPR $USERID 1>&2 >/dev/null;}function add_poly { /bin/mkdir /home/$USERID/$USERID.inst && chmod -R 000 /home/$USERID/$USERID.inst 1>&2 >/dev/null;}function add_forward { /bin/echo """Match User $USERID X11Forwarding no AllowTcpForwarding no""" >> /etc/ssh/sshd_config;}function add_quota { /usr/sbin/setquota -u $USERID 0 $UQUOT 7500 10000 -a 1>&2 >/dev/null;}function add_nproc { /bin/echo "$USERID hard nprocs $UNPROC" >> /etc/security/limits.conf;}function add_logins { /bin/echo "$USERID - nlogins $ULOGNS" >> /etc/security/limits.conf;}function add_local {/bin/echo "- : $USERID : LOCAL" >> /etc/security/access.conf;}function add_groups { /usr/sbin/usermod -G $UGRP $USERID 1>&2 >/dev/null;}function add_cat {NEWCAT=:$UCATGR /usr/sbin/semanage user -a -L s0 -r "s0-s0$NEWCAT" -R user_r -P user $USERID 1>&2 >/dev/null; /usr/sbin/semanage login -a -s $USERID -r "s0-s0$NEWCAT" $USERID 1>&2 >/dev/null;}function add_seuser { /usr/sbin/semanage user -a -L s0 -r "s0-s0" -R user_r -P user $USERID 1>&2 >/dev/null; /usr/sbin/semanage login -a -s $USERID -r "s0-s0" $USERID 1>&2 >/dev/null;}# Main loop# Replace the parameters with the results of getopteval set -- "$RESULT"# Process the parameters# TODO: make poly optionalwhile [ $# -gt 0 ] ; do case "$1" in -h | --help) # Show help printf "$SCRIPT:$LINENO: %s\n" "Usage: $SCRIPT [options]" printf "$SCRIPT:$LINENO: %s\n" " Options:" printf "$SCRIPT:$LINENO: %s\n" " [-h][--help] | View this help" printf "$SCRIPT:$LINENO: %s\n" " [-L][--local] | Optional: Disabled by default" printf "$SCRIPT:$LINENO: %s\n" " [-f][--forward] | Optional: Disabled by default" printf "$SCRIPT:$LINENO: %s\n" " [-i][--identity] identity | Required: User name" printf "$SCRIPT:$LINENO: %s\n" " [-p][--password] password | Required: Strong password" printf "$SCRIPT:$LINENO: %s\n" " [-c][--comment] comment | Optional: Disabled by default" printf "$SCRIPT:$LINENO: %s\n" " [-g][--groups] groups | Tunable: Defaults to realusers,sshusers" printf "$SCRIPT:$LINENO: %s\n" " [-l][--logins] number of logins | Tunable: Defaults to 3" printf "$SCRIPT:$LINENO: %s\n" " [-n][--nproc] number of processes| Tunable: Defaults to 15" printf "$SCRIPT:$LINENO: %s\n" " [-r][--range] range | Optional: Disabled by default" printf "$SCRIPT:$LINENO: %s\n" " [-q][--quota] number of blocks | Tunable: Defaults to 10000 blocks" printf "$SCRIPT:$LINENO: %s\n" " [-e][--expire] date | Optional: Disabled by default" exit 0 ;; -i | --identity) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Identity for [-i][--identity] is missing" >&2 exit 192 fi USERID="$1" ;; -p | --password) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Password for [-p][--password] is missing" >&2 exit 192 fi UPASSWD="$1" ;; -c | --comment) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Comment for [-c][--comment] is missing" >&2 exit 192 fi UCOMMNT="$1" ;; -g | --groups) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Groups for [-g][--groups] are missing" >&2 exit 192 fi UGRP="$1" ;; -l | --logins) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Number of logins for [-l][--logins] is missing" >&2 exit 192 fi ULOGNS="$1" ;; -n | --nproc) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Number of processes for [-n][--nproc] is missing" >&2 exit 192 fi UNPROC="$1" ;; -L | --local) shift ULOCL=1 ;; -r | --range) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Range for [-r][--range] is missing" >&2 exit 192 fi UCATGR="$1" ;; -f | --forward) shift UFORWRD=1 ;; -q | --quota) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Quota for [-q][--quota] is missing" >&2 exit 192 fi UQUOT="$1" ;; -e | --expire) shift if [ $# -eq 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "Expiration date for [-e][--expire] is missing" >&2 exit 192 fi UEXPR="$1" ;; esac shiftdoneif [ -z "$USERID" ] ; then printf "$SCRIPT:$LINENO: %s\n" "Identity missing" >&2 exit 192fiif [ -z "$UPASSWD" ] ; then printf "$SCRIPT:$LINENO: %s\n" "Password missing" >&2 exit 192fi# Processingif test -n "$USERID" ; then add_user; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_user: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added user: $USERID";else printf "$SCRIPT:$LINENO: %s\n" "no identity specified: should not be here"; exit 192fisleep 1;if test -n "$UPASSWD" ; then add_user_passwd; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_passwd: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added passwd: $UPASSWD";else printf "$SCRIPT:$LINENO: %s\n" "no password specified: should not be here"; exit 192fisleep 1;if test "$UCOMMNT" -ne 0 ; then add_comment; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_comment: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added comment: $UCOMMNT";else printf "$SCRIPT:$LINENO: %s\n" "no comment specified: skipping";fisleep 1;if [ "$UGRP" != "realusers,sshusers" ] ; then add_groups; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_groups: FAIL"; exit 192 fi printf "%s\n" "added groups: $UGRP";else add_groups; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_groups: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "no groups specified: realusers,sshusers";fisleep 1;if [ $UEXPR != "0" ] ; then add_expire; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_expire: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added expire: $UEXPR";else printf "$SCRIPT:$LINENO: %s\n" "no expire specified: skipping";fisleep 1;if [ $? -eq 0 ] ; then add_poly; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_poly: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "poly mandatory: added poly"else printf "$SCRIPT:$LINENO: %s\n" "should not be here"; exit 192fisleep 1;if [ $UFORWRD -lt 1 ] ; then add_forward; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add forward: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "forward not specified: added forward";else printf "$SCRIPT:$LINENO: %s\n" "forward specified: skipping";fisleep 1;if [ $UQUOT -ne 0 ] ; then add_quota; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_quota: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added quota: $UQUOT";else printf "$SCRIPT:$LINENO: %s\n" "should not be here"; exit 192fisleep 1;if [ $UNPROC -ne 0 ] ; then add_nproc; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_nproc: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added nproc: $UNPROC";else printf "$SCRIPT:$LINENO: %s\n" "should not be here"; exit 192fisleep 1;if [ $ULOGNS -ne 0 ] ; then add_logins; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_logins: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added logins: $ULOGNS"else printf "$SCRIPT:$LINENO: %s\n" "should not be here"; exit 192fisleep 1;if [ $ULOCL -lt 1 ] ; then add_local; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_local: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "local not specified: added local";else printf "$SCRIPT:$LINENO: %s\n" "local specified: skipping";fisleep 1;if [ $UCATGR != "0" ] ; then add_cat; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_cat: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added cat: $UCATGR";else add_seuser; if [ $? -gt 0 ] ; then printf "$SCRIPT:$LINENO: %s\n" "add_seuser: FAIL"; exit 192 fi printf "$SCRIPT:$LINENO: %s\n" "added seuser";fi# Clean upexit $EXITSTATUS#EOF#TODO: cron.allow, at.allow, roles, password aging, list, remove, modify, logging