>
>I have just inherited a large group of new UNIX "illiterate" users
>that will be working under a restricted environment. Instead of
>attempting to train/teach these people how to change their password
>and giving them access to the shell, does any one have a CGI script
>that allows one to change their password via the web ?
>
Sorry it has taken so long but this was item 10 on the to do list and
I had to make sure I could also get a version working for HP-UX 10.2
and for NIS. Included at the bottom is the Perl 5 source for the the
Solaris passwd version. If you want a Solaris NIS or HP-UX 10.2
version let me know.
The program is originally from the Perl Journal, Summer 98 written by
Lincoln D Stein. I have modified it to use the expect module instead
of the chat2 module as he mentioned in the article.
Many thanks to Jeff Putsch <putsch@unitrode.com> for pointing me to
the article.
Other suggestions were discarded for various reasons:
- Set the shell for passwd. Unfortunately the users still have to log
in.
- Use Expect. I sort of do in this script by using the expect module.
- Use an interface to the popassd program called wwwpass. Since I
didn't want another daemon to mess around with I didn't use this
avenue. Also the program set found at
ftp://ray.ucs.sfu.ca/Public/Account_Management/management.tar and
ftp://ray.ucs.sfu.ca/Public/Account_Management/lib.tar.
Thanks to:
Rik Schneider <rik@netasset.com>
Chris Tubutis <chris@tci.com>
Robert Rose <Robert.Rose@ag.gov.au>
Mick Morgan <sun-managers@open.gov.uk>
Richard Bosire <bosire@ns1.africaonline.co.ke>
agardine@lsil.com <Alistair Gardiner>
Bjorn E. Torsteinsen <Bjorn.Torsteinsen@nfh.uit.no>
Jeff Putsch <putsch@unitrode.com>
Ken McKinlay
Unix Administrator
Lockheed Martin Canada, Kanata
(613) 599-3280 x861
Ken.McKinlay@lmco.ca
------------------
#!/usr/local/bin/perl5
# preliminaries to satisfy taint checks
$ENV{PATH} = '/bin:/usr/bin';
$ENV{IFS} = '';
# Prevent buffering problems
$| = 1;
use CGI qw/:standard :html3/;
# display the HTML header
print header,
start_html(-title=>'Change Unix Password',
-bgcolor=>'white'),
h1('Change your Unix password');
import_names('Q');
TRY: {
last TRY unless $Q::user;
my ($rv,$msg) = check_consistency();
do_error($msg),last TRY unless $rv;
($rv,$msg) = set_passwd($Q::user,$Q::old,$Q::new1);
do_error($msg),last TRY unless $rv;
print $msg;
$OK++;
}
create_form() unless $OK;
print
p,
a({href=>"$Q::referer" || referer() },"[ EXIT SCRIPT]"),
hr,
a({href=>'/'},'Home page'),
end_html;
sub check_consistency {
return (undef,'Please fill in the user name field.') unless $Q::user;
return (undef,'Please fill in the old password field.') unless $Q::old;
return (undef,'Please fill in the new password fields.') unless $Q::new1 &&
$Q::new2;
return (undef,"New password fields don't match.") unless $Q::new1 eq
$Q::new2;
return (undef,"Suspicious user name $Q::user.") unless
$Q::user=~/^\w{3,8}$/;
return (undef,'Suspiciously long old password.') unless length($Q::old) <
30;
return (undef,'Suspiciously long new password.') unless length($Q::new1) <
30;
my $uid = (getpwnam($Q::user))[2];
return (undef,"Unknown user name $Q::user.") if $uid eq '';
return (undef,"Can't use this script to set root password.") if $uid == 0;
return 1;
}
sub set_passwd ($$$) {
use Expect;
$Expect::Log_Stdout = 0;
my $TIMEOUT = 2;
my $PASSWD = "/bin/passwd";
my $SU = '/bin/su';
my($user,$old,$new) = @_;
# spawn the su command using expect
my $passwd = Expect->spawn("$SU $user -c \"$PASSWD $user\"") || return
(undef,"Couldn't open $SU $user -c $PASSWD");
# wait for su to prompt for password
my $rv = $passwd->expect($TIMEOUT,
"Password:",
"su: Unknown id: $user");
$rv == 2 && return (undef,"User $user unknown.");
$rv || return (undef,"Didn't get su password prompt.");
# send the password for the user
print $passwd "$old\r";
# wait for passwd to prompt for old password
$rv = $passwd->expect($TIMEOUT,
"Old password:",
"su: Sorry");
$rv == 2 && return (undef,"Old password is incorrect.");
$rv || return (undef,"Didn't get prompt for old password.");
# print old password
print $passwd "$old\r";
$rv = $passwd->expect($TIMEOUT,
"New password:",
"Sorry.");
$rv == 2 && return (undef,"Old password is incorrect.");
$rv || return (undef,"Timed out without seeing prompt for new password.");
# print new password
print $passwd "$new\r";
$rv = $passwd->expect($TIMEOUT,
"Re-enter new password:",
"Please use a longer password.",
"Passwords must differ by at least 3 positions",
"Password must contain at least two alphabetic
characters and at least one numeric or special character.");
$rv == 2 && return (undef,"Please use a longer password.");
$rv == 3 && return (undef,"Passwords must differ by at least 3 positions.");
$rv == 4 && return (undef,"Password must contain at least two alphabetic
characters and at least one numeric or special character.");
$rv || return (undef,"Timed out without seeing second prompt for new
password.");
# reconfirm password
print $passwd "$new\r";
$rv = $passwd->expect($TIMEOUT,
"They don't match; try again.");
$rv == 1 && return (undef,"Second password doesn't match.");
$passwd->hard_close();
return (1,"Password changed successfully for $Q::user.");
}
sub create_form {
print
start_form,
table(
TR({align=>RIGHT},
th('User name'), td(textfield(-name=>'user')),
th('Old password'),td(password_field(-name=>'old'))),
TR({align=>RIGHT},
th('New password'),td(password_field(-name=>'new1')),
th('Confirm new password'),td(password_field(-name=>'new2'))),
),
p,
hidden(-name=>'referer',-value=>referer()),
table(
TR(
td({align=>LEFT},submit('Change Password')),
td({align=>RIGHT},reset)),
),
end_form;
}
sub do_error ($) {
print "<CENTER><FONT COLOR='red' SIZE='+1'>";
print b('Error: '),shift," Password is not changed.";
print "</FONT></CENTER>";
}
This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:12:51 CDT