Re: Changing a user's password non-interactively?



Chris

here is is a perl script I wrote for our windows admins to interactivly
change passwords from a domain controller - to hell with security :)
You need expect and a setpass.expect script which ill add

you probably couldnt use this verbatim, but it may give you some ideas
(rexec, ssh, etc... )

#!/usr/bin/perl -w

use strict;
#use diagnostics;
use POSIX qw/uname/;
use POSIX qw/strftime/;
use Carp;

$|++;

# Change this to 1 to
# enable undos...
my $UNDO = 0;

my ($os, $hostname, undef)=POSIX::uname();
my ($host, undef)=split(/\./, $hostname);
my $OS = lc($os);

# APACHE Pawword File Location. if what is passed does not
# match this, exit with a nasty warning. If you have more
# than one location, add another variable...
# $APACHEDEFAULT1 etc...
my $APACHEDEFAULT = "/etc/httpd/conf/passwords";
my $APACHEDEFAULT1 = "/var/www/conf/passwords";

# Dispatch table is dependent an these vars
my ( $MODE, $USERNAME, $NEWPASS, $APACHECONF, @THINGS );
$MODE = $USERNAME = $NEWPASS = $APACHECONF = "UNDEFINED";

# Define all input dependant vars here
unless ( defined ($ARGV[0]) and $ARGV[0] =~ m/-(p|a|d|ha|hd)/ )
{
print "500 - DONE - $host - Missing or bad mode\n";
exit;
}

if ( defined $ARGV[0] ) { $MODE = $ARGV[0] }
if ( defined $ARGV[1] ) { $USERNAME = $ARGV[1] }
if ( defined $ARGV[2] ) { $NEWPASS = $ARGV[2] }
if ( defined $ARGV[3] ) { $APACHECONF = $ARGV[3] }

######################
## BEGIN exceptions ##
######################
# Seperate HACMP from AIX...
my @HACMP_CLUSTER=("NODE1",
"NODE2",
"NODE3",
"NODE4");

if ( $OS eq "aix" )
{
HALOOP: for (@HACMP_CLUSTER)
{
$OS = "hacmp" if ( $_ eq $host );
last HALOOP if ( $OS eq "HACMP" );
}
}
# AIX and HACMP are separated

if ( $MODE eq "-hd" )
{
if ( defined ( $ARGV[2] ) )
{
$NEWPASS = "NOTHING";
$APACHECONF = $ARGV[2];
}
}

if ( $USERNAME eq "root" )
{
print "500 - DONE - User Maintenance for $USERNAME not allowed";
exit;
}

if ( $APACHECONF ne "UNDEFINED" )
{
if ( $APACHECONF eq $APACHEDEFAULT1 )
{
$APACHEDEFAULT = $APACHEDEFAULT1;
}
else
{
print "500 - DONE - File mismatch ($APACHECONF !=
$APACHEDEFAULT)";
exit;
}
}

# if the apache config file does not exist,
# we'll add -c to htpasswd and let htpasswd
# create it.
my $APACHEARGS = "";
if ( ! -e "$APACHECONF" ) { $APACHEARGS= "-c" }

# This next line is too long to enter into
# the Dispatch table...
my $AIXADDU="/usr/bin/mkuser pgrp=staff groups=staff
home=/home/$USERNAME shell=/usr/bin/ksh gecos=$USERNAME $USERNAME";

#######################
## END of exceptions ##
#######################


# Format: MODE => ( COMMAND, UNDOCMD, ACTION TAKEN, ERROR_CODES )
# Be careful of the COMMAND and UNDOCMD - they are dependant on your
# OS and of how yor binaries are installed.
my %cmd=( "-p" => { "COMMAND" => { "linux" =>
"/usr/local/bin/setpass.expect $USERNAME $NEWPASS",
"aix" =>
"/usr/local/bin/setpass.expect $USERNAME $NEWPASS &&
/usr/bin/pwdadm -c
$USERNAME",
"hacmp" => "" },
"ACTION" => "Password Changed",
"ERRORS" => { "$OS:256" => "$USERNAME Does
not exist",
"$OS:32512" => "Unable to find
setpass.expect" } },

"-d" => { "COMMAND" => { "linux" => "/usr/sbin/userdel -r
$USERNAME",
"aix" => "/usr/sbin/rmuser -p
$USERNAME",
"hacmp" => "" },
"ACTION" => "Deleted",
"ERRORS" => { "$OS:1536" => "$USERNAME Does
not exist"} },

"-a" => { "COMMAND" => { "linux" => "/usr/sbin/useradd
$USERNAME &&

/usr/local/bin/setpass.expect $USERNAME $NEWPASS",
"aix" => "$AIXADDU &&

/usr/local/bin/setpass.expect $USERNAME $NEWPASS &&
/usr/bin/pwdadm -c
$USERNAME",
"hacmp" => "" },
"UNDOCMD" => { "linux" => "/usr/sbin/userdel -r
$USERNAME",
"aix" => "/usr/sbin/rmuser -p
$USERNAME" },
"ACTION" => "Added",
"ERRORS" => { "$OS:2304" => "$USERNAME
exists",
"$OS:32512" => "Unable to find
setpass.expect" } },

"-ha" => { "COMMAND" => { "linux" => "/usr/bin/htpasswd -b
-d $APACHEARGS $APACHECONF $USERNAME $NEWPASS",
"aix" =>
"/var/www/bin/htpasswd -b -d $APACHEARGS $APACHECONF $USERNAME
$NEWPASS" },
"UNDOCMD" => { "linux" => "/usr/bin/htpasswd -D
$APACHECONF $USERNAME",
"aix" =>
"/var/www/bin/htpasswd -b -d $APACHECONF $USERNAME `echo \$RANDOM`" },
"ACTION" => "Added to $APACHECONF" },

"-hd" => { "COMMAND" => { "linux" => "/usr/bin/htpasswd -D
$APACHECONF $USERNAME",
"aix" =>
"/var/www/bin/htpasswd -b -d $APACHECONF $USERNAME `echo \$RANDOM`" },
"ACTION" => "Deleted from $APACHECONF" } );

# Check for the correct parameters for the runtime mode
# you are in, run the command and check for errors
# all exits should be clean and return vals checked.
if ( &checkparms($MODE, $USERNAME, $NEWPASS, $APACHECONF) == 0 )
{
qx/$cmd{$MODE}{'COMMAND'}{$OS}/;
check_error($?);
}
else
{
# see checkparms() for info on @THINGS
print "500 - DONE - $host - @THINGS not defined";
}
exit;

###############
sub check_error
###############
{
$_=shift;
my $err="$OS:$_";
my $msg = "$USERNAME $cmd{$MODE}{'ACTION'}";
$msg = $cmd{$MODE}{'ERRORS'}{$err} if ( defined
($cmd{$MODE}{'ERRORS'}{$err}) );

open (LOGFILE, ">>/var/log/user_maint.log") or
carp "500 - DONE - Unable to open logfile";

# If we have an undo command for anything but a succesful return
# Lets run it now and log the results
if ( $UNDO == 1 and $_ > 0 )
{
qx/$cmd{$MODE}{'UNDO'}/ if ( defined ($cmd{$MODE}{'UNDO'}) );
$msg = "Undo command was run (USER = $USERNAME, MODE = $MODE)";
}

( $_ == 0 ) ? print "200 - DONE - $host - Sucess ($_) - $msg\n"
: print "500 - DONE - $host - Failure ($_) - $msg\n";

my $now = strftime "%m/%d/%Y %H:%M:%S", (localtime);
print LOGFILE "$now - $_ - $USERNAME - $msg\n";

close (LOGFILE) or carp "Unable to close logfile\n";
return 0;
}

##############
sub checkparms
##############
{
my $mode= shift;
my $username=shift;
my $newpass=shift;
my $apacheconf=shift;

if ( $mode eq "-a" or
$mode eq "-p" or
$mode eq "-d" or
$mode eq "-ha" or
$mode eq "-hd" )
{
push (@THINGS, "USERNAME") if ( $username eq "UNDEFINED" );
}

if ( $mode eq "-a" or
$mode eq "-p" or
$mode eq "-ha" )
{
push (@THINGS, "PASSWORD") if ( $newpass eq "UNDEFINED" );
}

if ( $mode eq "-ha" or
$mode eq "-hd" )
{
push (@THINGS, "HTTPD.CONF") if ($apacheconf eq "UNDEFINED" );
}

return ( scalar(@THINGS) == "0" ) ? 0 : 1;
}
__END__


setpass.expect script ->

#!/usr/local/bin/expect
# chpass.expect
# Expect script for adding a new user
#
# Uses /usr/bin/passwd(1) non-interactive
# username is passed as 1st arg, passwd as 2nd

# assigned password value to $password
set password [lindex $argv 1]

# start /usr/bin/passwd with $argv0
spawn passwd [lindex $argv 0]
sleep 1

# wait for string "password"
expect "password:"
sleep 1

# send $password
send "$password\r"
sleep 1

# wait for string "password"
expect "password:"
sleep 1

# send $password
send "$password\r"
sleep 1
expect eof

my "production" version differs only in that I have the cspoc commands
built in...

.



Relevant Pages

  • Re: How to time out a command
    ... > I have a ksh script that calls another utility (command A). ... I once made the following script to do exactly that. ... # Runs a command and kills it, if necessary, after a given timeout. ... # 0<c<127 - job exited with this exit code ...
    (comp.unix.shell)
  • Re: [opensuse] postfix master.cf question
    ... Have you tried to use the command in mailbox_command as I suggested? ... The script is called ... echo Cannot save mail to file; exit $EX_TEMPFAIL;} ...
    (SuSE)
  • Re: Changing a users password non-interactively?
    ... You need expect and a setpass.expect script which ill add ... exit with a nasty warning. ... # Be careful of the COMMAND and UNDOCMD - they are dependant on your ...
    (comp.unix.aix)
  • Re: expect.pm - stdout buffering issue
    ... You're script is basically doing: ... Expect will run the command, then you tell it what you ...  Then you can sleep, or send another command ... found a way to get the script display the STDOUT correctly and log all ...
    (comp.lang.perl.misc)
  • Re: How to set a variable using ssh in a while loop?
    ... Here is the script, sorry that it's so ... What command do you think you are checking? ... unset appsrv ...
    (comp.unix.shell)

Loading