#!/bin/ksh # # rpkgadd: Remote Package Management for Solaris # # Author: Adam Ronthal # # Copyright (c) 2003, CiRBA Inc. http://www.cirba.com # This software is distributed under the terms of the X11 Public License. # Please type 'rpkgadd -l' for license terms. # # Description # ----------- # rpkgadd is a remote pkgadd tool to install Sun packages on remote machines # it requires sshd to be running on the target machine and ssh/scp to be # installed on the local machine. # # root or root-equivalent permissions are required on the target machine, # though the password is never sent in the clear. # # rsa or dsa keys are supported for authentication, though empty password # keys are not recommended for the root account. If empty passwords are # to be used, it is strongly recommended to create a root-equivalent # account (e.g. pkginstall) # ############################ # Settings and Environment # ############################ export PATH=/usr/bin:/usr/local/bin # Is this a NIS environment # NIS="no" # Remove keys # RMKEYS="yes" # Remove package source from remote server /var/spool/pkg when installed # DELPKG="yes" # Default is to install packages, not uninstall them # RMPKG="no" # Use DSA keys by default # KEYTYPE="dsa" # Use 'root' as the default remote root if not specified # REMOTE_ROOT="root" ############# # Functions # ############# rpkgadd -p -t -u [ -k rsa|dsa ] [ -mSehDl ] rpkgadd -b f_usage() { echo "USAGE: $0 -p -t -u \ [ -k rsa|dsa ] [ -mSehDl ]" echo " $0 -b " echo echo "EXAMPLES: $0 -p SMCwget -t somehost -u pkginstall" echo " $0 -b rpkgadd.conf" echo " $0 -d -p SMCwget -t somehost -u pkginstall" echo echo "Use '$0 -h' for detailed usage instructions" exit 1 } f_help() { cat< ./${CURPKG}.tar.gz echo "Transfering package to $TARGET" scp -q -i $MYHOME/.ssh/pkgkey ./${CURPKG}.tar.gz $REMOTE_ROOT@$TARGET:/var/spool/pkg echo "Installing package on $TARGET..." ssh -i $MYHOME/.ssh/pkgkey -l $REMOTE_ROOT $TARGET "cd /var/spool/pkg && \ gzcat $CURPKG.tar.gz | tar xf -; rm $CURPKG.tar.gz; pkgadd $CURPKG" echo "Cleaning up..." rm $CURPKG.tar.gz if [ "$DELPKG" = "yes" ]; then ssh -i $MYHOME/.ssh/pkgkey -l $REMOTE_ROOT $TARGET "cd /var/spool/pkg \ && rm -Rf $CURPKG" fi } f_remove_keys() { ssh -i $MYHOME/.ssh/pkgkey -l $REMOTE_ROOT $TARGET "ksh -c 'if [ -f \ ~${REMOTE_ROOT}/.ssh/authorized_keys ]; then cat \ ~${REMOTE_ROOT}/.ssh/authorized_keys | sed -e /pkgkey\$/d > \ ~${REMOTE_ROOT}/.ssh/ak.tmp && mv ~${REMOTE_ROOT}/.ssh/ak.tmp \ ~${REMOTE_ROOT}/.ssh/authorized_keys; fi; if [ -f \ ~${REMOTE_ROOT}/.ssh/authorized_keys2 ]; then cat \ ~${REMOTE_ROOT}/.ssh/authorized_keys2 | sed -e /pkgkey\$/d > \ ~${REMOTE_ROOT}/.ssh/ak2.tmp && mv ~${REMOTE_ROOT}/.ssh/ak2.tmp \ ~${REMOTE_ROOT}/.ssh/authorized_keys2; fi'" } f_add_keys() { # Add the public key to the target host's authorized_keys files. We want # to support all versions of SSH, so we populate both the authorized_keys # and the authorized_keys2 files. # cat $MYHOME/.ssh/pkgkey.pub | ssh -l $REMOTE_ROOT $TARGET "ksh -c 'if \ [ ! -d ~/.ssh ]; then mkdir -m 0700 ~/.ssh; fi; cat - \ >>~/.ssh/authorized_keys2; cp -p \ ~/.ssh/authorized_keys2 ~/.ssh/authorized_keys; chmod -R 0700 ~/.ssh'" } f_main_engine() { echo "Target host is $TARGET" # Check if we're adding or removing a package # if [ "$RMPKG" != "yes" ]; then # We standardize the package format to the traditional Solaris # format. If the package is in DaTaStReAm format, we convert # it using pkgtrans. if [ -d $PACKAGE ]; then PTYPE=standard echo "Package is standard format." elif [ -f $PACKAGE ]; then DS=`head -1 $PACKAGE | grep "DaTaStReAm"` if [ "x$DS" != "x" ]; then PTYPE=datastream echo "Package is in DaTaStReAm format. Translating." TRANSD_PACKS=`pkgtrans -o $PACKAGE . all 2>&1 | grep \ "Transferring" | sed -e 's/.*.*//g'` fi else echo "Cannot determine format of package." exit 1 fi # Since the translation process could result in multiple packages, # we deal with that here by getting the name(s) of the packages from # from the output of pkgtrans above, and looping through them. # if [ "x$PTYPE" = "xstandard" ]; then f_process_pkg $PACKAGE else for i in $TRANSD_PACKS; do f_process_pkg $i rm -Rf $i done fi # We're removing a package here. # else ssh -i $MYHOME/.ssh/pkgkey -l $REMOTE_ROOT $TARGET "pkgrm ${PACKAGE}" fi } ############# # Main # ############# # We need to be called with at least one argument # if [ $# -eq 0 ]; then f_usage exit 1 fi # Check the command parameters # while getopts p:t:u:k:b:mSehDl args; do case $args in p) PACKAGE=$OPTARG ;; t) TARGET=$OPTARG ;; u) REMOTE_ROOT=$OPTARG ;; k) KEYTYPE=$OPTARG ;; m) DELPKG="no" ;; S) RMKEYS="no" ;; b) BATCHCONFIG=$OPTARG BATCHMODE="yes" ;; e) EXPUNGE="yes" ;; D) RMPKG="yes" ;; h) HELP="yes" ;; l) LIC="yes" ;; *) echo "Invalid option." f_usage ;; esac done # Respond to special requests # if [ "$HELP" = "yes" ]; then f_help exit 1 fi if [ "$LIC" = "yes" ]; then f_show_lic exit 1 fi # Generate a temporary (if necessary) dsa or rsa key for this session. # It will be removed from the target host's authorized keys file # automatically at the end of the run if the -r flag is NOT specified # # Get the current user and home directory # ME=`id | sed -e 's/).*//g' -e 's/.*(//g'` if [ "$NIS" = "yes" ]; then export MYHOME=`ypcat passwd | grep $ME | cut -d: -f6` else export MYHOME=`grep $ME /etc/passwd | cut -d: -f6` fi # Handle the creation and/or deletion of SSH keys # if [ "$EXPUNGE" = "yes" ]; then if [ -f $MYHOME/.ssh/pkgkey.pub ]; then rm $MYHOME/.ssh/pkgkey.pub fi if [ -f $MYHOME/.ssh/pkgkey ]; then rm $MYHOME/.ssh/pkgkey fi fi if [ ! -f $MYHOME/.ssh/pkgkey.pub ]; then if [ ! -d $MYHOME/.ssh ]; then mkdir -m 0700 $MYHOME/.ssh fi echo "----------------------------------------------------------------" echo "Hit return when asked for password. authorized_keys files will" echo "be removed from the target host once packages are added unless " echo "the '-r' is specified on the command line. " echo "----------------------------------------------------------------" ssh-keygen -t $KEYTYPE -C pkgkey -f $MYHOME/.ssh/pkgkey fi if [ "$BATCHMODE" = "yes" ]; then while read -u3 i; do # READ FROM FD3 TO AVOID INTERACTIVE # CONFLICTS WITH pkgadd if [ "x`echo $i | egrep '^[^# ]'`" = "x" ]; then continue fi export TARGET=`echo $i | cut -f1 -d:` export REMOTE_ROOT=`echo $i | cut -f2 -d:` export RMPKG=`echo $i | cut -f3 -d:` export RMKEYS=`echo $i | cut -f4 -d:` export DELPKG=`echo $i | cut -f5 -d:` export KEYTYPE=`echo $i | cut -f6 -d:` export PKGS_TO_PROCESS=`echo $i | awk 'BEGIN { FS = ":"} \ { for ( k = 7; k<= NF; k++ ) print $k }'` # Add keys to the target host # f_add_keys for p in $PKGS_TO_PROCESS; do export PACKAGE=$p f_main_engine done # If we are removing the rsa/dsa ssh keys, we do that here. # if [ $RMKEYS = "yes" ]; then f_remove_keys fi done 3<$BATCHCONFIG else # Add keys to the target host # f_add_keys f_main_engine # If we are removing the rsa/dsa ssh keys, we do that here. # if [ $RMKEYS = "yes" ]; then f_remove_keys fi fi