#!/bin/sh
##
##  pamtool -- OpenPKG PAM Auxiliary Tool
##  Copyright (c) 2000-2018 Ralf S. Engelschall <http://engelschall.com/>
##
##  Permission to use, copy, modify, and distribute this software for
##  any purpose with or without fee is hereby granted, provided that
##  the above copyright notice and this permission notice appear in all
##  copies.
##
##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
##  SUCH DAMAGE.
##

#   program name, version and date
progname="pamtool"
progvers="0.9.0"
progdate="11-Mar-2002"

#   the OpenPKG instance information
l_prefix="@l_prefix@"
l_platform="@l_platform@"

#   default parameters
verbose=no
help=no
add=no
remove=no
smart=no
name=""
id=""

#   iterate over argument line
while [ $# -gt 0 ]; do
    opt=$1
    case $opt in
        -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
           *) arg='' ;;
    esac
    case $opt in
        -v|--verbose ) verbose=yes   ;;
        -h|--help    ) help=yes      ;;
        -a|--add     ) add=yes       ;;
        -r|--remove  ) remove=yes    ;;
        -s|--smart   ) smart=yes     ;;
        --name=*     ) name=$arg     ;;
        --id=*       ) id=$arg       ;;
        -*           ) help="Invalid option \`$opt'"; break ;;
        *            ) break         ;;
    esac
    shift
done
if [ ".$help" = .yes ]; then
    echo "$progname --add|--remove --name=NAME [--smart] [--id=ID]";
    exit 0
fi
if [ ".$add" = .no -a ".$remove" = .no ]; then
    echo "$progname:ERROR: either option -a/--add or -r/--remove have to be specified" 1>&2
    exit 1
fi
if [ ".$add" = .yes -a ".$remove" = .yes ]; then
    echo "$progname:ERROR: option -a/--add and -r/--remove cannot be specified in parallel" 1>&2
    exit 1
fi
if [ ".$name" = . ]; then
    echo "$progname:ERROR: option --name has to be specified" 1>&2
    exit 1
fi
if [ ".$id" = . ]; then
    id="$l_prefix:$name"
fi


#   find a reasonable temporary location
if [ ".$TMPDIR" != . ]; then
    tmpdir="$TMPDIR"
elif [ ".$TEMPDIR" != . ]; then
    tmpdir="$TEMPDIR"
else
    tmpdir="/tmp"
fi
tmpfile="$tmpdir/pamtool.$$.tmp"

#   determine PAM information from OpenPKG configuration
if [ ! -f "$l_prefix/etc/rc" ]; then
    echo "$progname:$ERROR: OpenPKG run-command facility not found under $l_prefix" 1>&2
    exit 1
fi
pam_enable=`$l_prefix/bin/openpkg rc --query pam_enable`
pam_cfgloc=`$l_prefix/bin/openpkg rc --query pam_cfgloc`
pam_modpfx=`$l_prefix/bin/openpkg rc --query pam_modpfx`

#   perform operation
if [ ! -f "$l_prefix/lib/openpkg/rpmtool" ]; then
    echo "$progname:$ERROR: OpenPKG rpmtool not found under $l_prefix/sbin/" 1>&2
    exit 1
fi
rpmtool_config="$l_prefix/lib/openpkg/rpmtool config"
if [ ".$smart" = .yes ]; then
    rpmtool_config="$rpmtool_config -s"
fi
if [ ".$add" = .yes ]; then
    #
    #   add a PAM entry
    #

    #   determine platform specific PAM entries
    ( case "$l_platform" in
          *-freebsd* ) 
              echo "auth     sufficient ${pam_modpfx}pam_opie.so no_warn no_fake_prompts"
              echo "auth     requisite  ${pam_modpfx}pam_opieaccess.so no_warn allow_local"
              echo "auth     required   ${pam_modpfx}pam_unix.so try_first_pass"
              echo "account  required   ${pam_modpfx}pam_unix.so"
              echo "password required   ${pam_modpfx}pam_permit.so"
              echo "session  required   ${pam_modpfx}pam_permit.so"
              ;;
          *-linux* ) 
              echo "auth     required   ${pam_modpfx}pam_unix_auth.so shadow nodelay"
              echo "auth     required   ${pam_modpfx}pam_nologin.so"
              echo "account  required   ${pam_modpfx}pam_unix_acct.so"
              echo "password required   ${pam_modpfx}pam_unix_passwd.so shadow nullok use_authtok" 
              echo "session  required   ${pam_modpfx}pam_unix_session.so" 
              echo "session  required   ${pam_modpfx}pam_limits.so"
              ;;
          *-sunos* ) 
              echo "auth     required   ${pam_modpfx}pam_unix.so try_first_pass"
              echo "account  required   ${pam_modpfx}pam_unix.so"
              echo "password required   ${pam_modpfx}pam_unix.so" 
              echo "session  required   ${pam_modpfx}pam_unix.so" 
              ;;
          *-aix* ) 
              echo "auth     required   ${pam_modpfx}pam_aix try_first_pass"
              echo "account  required   ${pam_modpfx}pam_aix"
              echo "password required   ${pam_modpfx}pam_aix" 
              echo "session  required   ${pam_modpfx}pam_aix" 
              ;;
          * ) 
              echo "auth     required   ${pam_modpfx}pam_unix.so try_first_pass"
              echo "account  required   ${pam_modpfx}pam_unix.so"
              echo "password required   ${pam_modpfx}pam_unix.so" 
              echo "session  required   ${pam_modpfx}pam_unix.so" 
              ;;
      esac
    ) >$tmpfile
     
    #   add application name prefix if using combined configuration
    if [ -f $pam_cfgloc ]; then
        sed -e "s;^;$name ;" <$tmpfile >$tmpfile.n
        mv $tmpfile.n $tmpfile
    fi
    
    #   create entry
    if [ -f $pam_cfgloc ]; then
        if [ ".$verbose" = .yes ]; then
            echo "++ adding entry to $pam_cfgloc"
        fi
        $rpmtool_config -a -i $id $pam_cfgloc <$tmpfile || exit $?
    elif [ -d $pam_cfgloc ]; then
        if [ ".$verbose" = .yes ]; then
            echo "++ adding entry to $pam_cfgloc/$name"
        fi
        $rpmtool_config -a -i $id $pam_cfgloc/$name <$tmpfile || exit $?
    fi

elif [ ".$remove" = .yes ]; then
    #
    #   remove a PAM entry
    #

    #   remove entry
    if [ -f $pam_cfgloc ]; then
        if [ ".$verbose" = .yes ]; then
            echo "++ removing entry from $pam_cfgloc"
        fi
        $rpmtool_config -r -i $id $pam_cfgloc || exit $?
    elif [ -d $pam_cfgloc ]; then
        if [ ".$verbose" = .yes ]; then
            echo "++ removing entry from $pam_cfgloc/$name"
        fi
        $rpmtool_config -r -i $id $pam_cfgloc/$name || exit $?
        if [ ! -s $pam_cfgloc/$name ]; then
            rm -f $pam_cfgloc/$name >/dev/null 2>&1 || true
        fi
    fi
fi

#   cleanup
rm -f $tmpfile
exit 0

