#!/usr/bin/perl ############################################################################ # Simple CGI script that uses smbpasswd to allow a user to change their # password on a Windows domain controller. # # Written 2013-03-02 by Lester Hightower ############################################################################ use strict; use CGI qw(:standard); use IPC::Open3; use Symbol 'gensym'; my $DOM_CONTROLLER = '10.113.20.20'; my $EXE_SMBPASSWD = '/usr/bin/smbpasswd'; my $q = CGI->new; if (uc($q->request_method()) eq 'POST') { try_change_passwd($q); } else { send_change_form($q); } exit; ############################################################################ ############################################################################ ############################################################################ sub send_change_form($) { my $q=shift @_; print $q->header('text/html'); my @form_elements = ( { 'name' => 'Username', 'html' => textfield(-name=>'username', -value=>'',-size=>20,-maxlength=>80) }, { 'name' => 'Current Password', 'html' => password_field(-name=>'old_passwd', -value=>'',-size=>20,-maxlength=>80), }, { 'name' => 'New Password', 'html' => password_field(-name=>'new_passwd', -value=>'',-size=>20,-maxlength=>80), }, { 'name' => 'Retype new password', 'html' => password_field(-name=>'new_passwd2', -value=>'',-size=>20,-maxlength=>80), }, ); print "\n" . "Change your Windows domain password\n" . "\n" . "

Change your Windows domain password

\n" . start_form(-method=>'POST') . "\n" . make_form_table_fields($q, \@form_elements) . "\n" . "
" . submit(-name=>'btn_chpasswd', -value=>'Change Password') . "
\n" . end_form . "\n" . "\n"; return; } sub make_form_table_fields($$) { my $q=shift @_; my $form_elements=shift @_; my $t=''; foreach my $fe (@{$form_elements}) { my $name=$fe->{name}; my $html=$fe->{html}; $t.="$name$html\n"; } return $t; } ############################################################################ sub try_change_passwd($) { my $q=shift @_; print $q->header('text/html'); my $username = $q->param('username'); my $old_passwd = $q->param('old_passwd'); my $new_passwd = $q->param('new_passwd'); my $new_passwd2 = $q->param('new_passwd2'); if ($username !~ m/^[a-z._0-9]+$/i) { print "Invalid username\n"; return; } if (length($new_passwd) < 1) { print "New password cannot be blank.\n"; return; } if ($new_passwd ne $new_passwd2) { print "Mismatch in new password verification.\n"; return; } my($wtr, $rdr, $err); $err = gensym; my @cmd=($EXE_SMBPASSWD,'-s','-U',$username,'-r',$DOM_CONTROLLER); #warn "LHHD: running - " . join(" ", @cmd) . "\n"; my $pid = open3($wtr, $rdr, $err, @cmd); print $wtr "$old_passwd\n$new_passwd\n$new_passwd2\n"; waitpid( $pid, 0 ); my $child_exit_status = $? >> 8; if ($child_exit_status == 0) { print "Password changed successfully."; } else { my $stdout=<$rdr>; my $stderr=<$err>; my $errmsg=$stdout; if (length($errmsg)) { $errmsg .= "\n-\n"; } $errmsg .= $stderr; print "Password change was not successful:
$errmsg
\n"; } return; }