Re: Automating password change

From: base60 (nobody_at_whitehouse.com)
Date: 09/07/05


Date: Wed, 07 Sep 2005 02:22:28 GMT


zipporuni wrote:
> Hi,
>
> I believe I have a pretty simple question that I'm hoping some of you can
> help me with, but I must provide some background information first; please
> bear with me.
>
> I have several hundred Sun and HP-UX machines on an Intranet that I need
> to change passwords on every month for my account and for an application
> account. All the machines are set up differently from each other
> regarding security, so there are some where I have to login as myself
> first, then su to the application account, or some I can login to the
> application account directly, and on some I must sudo. With some I can
> use telnet, others I can rlogin or remsh, and still others I can ssh. Not
> only that, but on some of them how I must login (telnet, ssh, su,
> or sudo) changes based on whether the password has expired or not.
> Suffice it to say there is quite a hodgepodge. What software is available
> on the machines (Perl, Expect, etc.) is also a hodgepodge. The one common
> element is all have Connect:Direct (NDM), which allows me to send a
> command or run scripts under my accounts without logging in. Like a fancy
> ssh or remsh.
>
> I have dabbled with Expect, and figured because of the complex environment
> I described, it would not be practical to try to write a complex script
> that would run from one place and connect to each machine, login, and
> change my passwords automatically.

Possible, but a bad idea: typos & bumps :)

> However, it would be quite practical
> to write a simple script to wrap around passwd that would run on each
> machine individually, and deploy it and execute it each month using
> Connect:Direct. I could have the whole job of changing the passwords done
> in seconds.
>
> If I choose Expect as the language to make the passwd
> wrapper script, I would also have to worry about deploying a
> run-time copy of Expect to those machines with my script.

No. Expect is only needed on the system from which the changes
are initiated.

> A minor
> problem is I can't do an "install" of Expect into a directory such as
> /usr/local/bin because I am not the administrator, nor do I have contact
> names of the SA's for all these hundreds of machines that are spread out
> everywhere. So the Expect needs to just run out of the directory I drop it
> in on each machine. No big deal so far, you're still with me, right?
>
> Here's a bigger problem: It appears Expect, in order to run, must have
> TCL loaded on the machine, and it must be more that just a file or two
> dropped where ever I like, as far as I can tell. Expect must have access
> to a TCL library or libraries. I have looked in the Expect documentation,
> readme's and install files, and I can't figure out a way that I might be
> able to compile a self-contained Expect executable, instead of an
> executable that relies on external files during run time. Does anyone
> know if that is possible or practical? I don't have a lot of experience
> with compiling or re-writing code or makefiles, so if somebody could have
> patience with me and let me know a step-by-step way that would be much
> appreciated.

expect and tcl are pretty simple to compile... the usual
./configure --prefix=<whatever> etc.

If you have a linux box, they're probably already installed.

>
> If anyone knows exactly what files in TCL are required by Expect, and it
> is a reasonably small quantity, then I suppose I could consider deploying
> those, although it is sounding like a mess.

Nope. Again, only required on one system. Since you posted this to
a .solaris group, you probably have a CD with the needed PDS stuff on
it.

>
> And finally, I've done a lot of reading on the subject of making passwd
> non-interactive so it can be scripted, and all practical roads I've read
> about seem to lead to Expect.

Yehp. That's really your only choice.

> Of course, I wouldn't have a way to install
> a custom version of the passwd command because it would have to have a set
> uid bit set to run as root, and I don't have that kind of access.

Hunh?

> So, if
> I am to do this, it seems I must wrap around the passwd command. If
> anyone has an idea of another approach to take, perhaps if there was an
> alternative scripting language to consider, that would be great. Your
> advice is appreciated. I would really like to get this job done in seconds
> rather than the hours it takes each month.

I've attached a ksh93/expect script that uses ssh and does sort of what
you want... and a bit more.

It wouldn't be difficult to add an associative array to link the
access method to the hostname/ip (bad idea, though).

On the odd chance that it needs to be said, sending cleartext passwords
over a wire is an invitation to be hacked.

ksh93 == /usr/dt/bin/dtksh on solaris



#!/bin/ksh93
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# Author: base60
# Purpose: ssh login to a range of systems & su to root
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
function expectIt {
                {
                print -- "#!${opt_E}"
                print -- "set timeout 10"
                print -- "set password ${PASSWORD}"
                print -- "spawn $opt_S $HOST -l ${opt_l}"
                print -- "set prompt \"(~|%|#|\\\\\\\\\\$) \""
                print -- "while 1 {"
                print -- " expect {"
                print -- " -re \$prompt {send \"su -\\\r\"; break}"
                print -- " \"assword:\" {send \$password\\\r; continue}"
                print -- " \"yes/no\" {send yes\\\r; continue}"
                print -- " \"Connection closed by remote host\" {puts \"Looks like you are wrapped out.\"; exit}"
                print -- " \"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\" { puts \"Bad ssh key for $HOST\"; exit}"
                print -- " \"Permission denied, please\" { puts \"Your password is invalid.\"; exit}"
                print -- " timeout {puts \"Timed out...\"; exit}"
                print -- " }"
                print -- " }"
                print -- "interact {"
                print -- " \"exit\" { send exit\\\r; break}"
                print -- " }"
                } > ${STUB}
        [[ -e ${STUB} ]] && chmod +x ${STUB} && ${STUB}
        }

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
function mainLoop {
        : "--->mainLoop"
        printf "${HIGHLIGHT}Password for $opt_l:${NORMAL} "
        stty -echo
        read -r PASSWORD
        stty echo
        print ""
        [[ -z ${PASSWORD} ]] && exit
        for (( cntr = $opt_b; cntr < $opt_e; cntr++ ))
                    do
                    HOST=$(printf "yourhost%03d.yourdomain.com" ${cntr})
                print -- "${HIGHLIGHT}---> $HOST ${NORMAL}"
                    ping ${HOST} ${PING_OPTS} > /dev/null 2>&1
                    if (( $? == 0)); then
                        expectIt
                        fi
                    done
        }

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
function debugOn {
        typeset -ft $(typeset +f)
        opt_d=1
        }

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
function usage {
        print -- "\nUsage: $ME -[b:de:E:l:hS:] (version $VERSION)"
        print -- " -b <Three digit beginning host>[$opt_b]"
        print -- " -d (Debug mode)"
        print -- " -e <Three digit ending host>[$opt_e]"
        print -- " -E <Absolute path to expect binary>[$opt_E]"
        print -- " -l <Login id>[$LOGNAME}"
        print -- " -h (Print this message)"
        print -- " -S <Absolute path to ssh binary>[$opt_S]"
        exit
        }

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
function cleanUp {
        rm ${STDERR} ${STDOUT} > /dev/null 2>&1
        stty echo
        ((opt_d == 0)) && [[ -e ${STUB} ]] && rm ${STUB} > /dev/null 2>&1
        exit
        }

#******************************************************************************
trap "trap - HUP QUIT INT TERM EXIT; cleanUp" HUP QUIT INT TERM EXIT
umask 077
OS=$(uname)
VERSION="1.0.5"
PS4='[$LINENO]+'
ME=${0##*/} ; typeset -r ME
STDERR="/tmp/$ME.STDERR" ; typeset -r STDERR
STDOUT="/tmp/$ME.STDOUT" ; typeset -r STDOUT
integer opt_d=0
integer opt_b=1
integer opt_e=200
integer opt_p=0
typeset opt_l="root"
typeset opt_E="/usr/bin/expect"
typeset opt_S="ssh"
HIGHLIGHT=`tput smso`
NORMAL=`tput rmso`
while getopts "b:de:E:hl:S:" C
        do case $C in
                b) opt_b=$OPTARG ;;# Set starting point
                d) . debugOn ;;# Enable debug
                e) opt_e=$OPTARG ;;# Set ending point
                E) opt_E=$OPTARG ;;# Absolute path to expect
                l) opt_l=$OPTARG ;;# Define Login ID
                h) usage ;;# Print help
                p) ((opt_p++)) ;;# Prompt for every system in range
                S) opt_S ;;# Absolute path to Ssh
        esac done
eval STUB='~'${opt_l}/.$$
case "$OS" in
        AIX) PING_OPTS=" 64 1" ;;
        SunOS) PING_OPTS=" 1"; export PATH=$PATH:/usr/sbin ;;
        Linux) PING_OPTS=" -c1" ;;
        * ) print -- "$OS not supported."
                exit;;
        esac
mainLoop



Relevant Pages

  • Re: Automating password change
    ... All the machines are set up differently from each other ... > use telnet, others I can rlogin or remsh, and still others I can ssh. ... it would not be practical to try to write a complex script ... > to write a simple script to wrap around passwd that would run on each ...
    (comp.unix.shell)
  • Automating password change
    ... I have several hundred Sun and HP-UX machines on an Intranet that I need ... to change passwords on every month for my account and for an application ... it would not be practical to try to write a complex script ... If I choose Expect as the language to make the passwd ...
    (comp.unix.solaris)
  • Automating password change
    ... I have several hundred Sun and HP-UX machines on an Intranet that I need ... to change passwords on every month for my account and for an application ... it would not be practical to try to write a complex script ... If I choose Expect as the language to make the passwd ...
    (comp.unix.shell)
  • Re: Shell Script or AppleScript?
    ... The script will need to take the latest file and post only ... that file to the other machines. ... You may also want to look into exchanging ssh keys so that you can ... Here is an outline of an AppleScript that can invoke a shell ...
    (comp.sys.mac.system)
  • Re: Hack attempts
    ... The machines from where these attempts come are already hacked: ... The script connecting on SSH with user test and guest is checking the ... SSH version and how the SSH reacts besides the plain version reply. ... I was on one hacking host because the rootkit on it - Fuck'it Rootkit ...
    (Fedora)