Created
October 6, 2011 19:39
-
-
Save evandhoffman/1268417 to your computer and use it in GitHub Desktop.
Change Active Directory password from a web browser.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# | |
# Evan Hoffman ([email protected]) | |
# 13 January, 2010 | |
# | |
# Base functionality from: http://search.cpan.org/~gbarr/perl-ldap/lib/Net/LDAP/FAQ.pod#..._in_MS_Active_Directory_? | |
print "Content-Type: text/html\n\n"; | |
use Net::LDAP; | |
use Unicode::Map8; | |
use Unicode::String qw(utf16); | |
use MIME::Base64; | |
use CGI::Lite; | |
# build the conversion map from your local character set to Unicode | |
my $charmap = Unicode::Map8->new('latin1') or die; | |
my $host = 'ldaps://activedirectory.example.com'; | |
my $bind_dn = 'CN=ldapuser,OU=Utility,OU=Users,DC=example,DC=com'; | |
my $bind_pw = 'secret'; | |
my $base_dn = 'DC=example,DC=com'; | |
my $search_filter = '(!(userAccountControl:1.2.840.113556.1.4.803:=2))'; | |
my $ldap = Net::LDAP->new($host) or die "$@"; | |
print '<html><title>Active Directory Password Changer $Id$</title><body>'; | |
die "REMOTE_USER not set.\n" unless $ENV{'REMOTE_USER'}; | |
unless ( $ENV{'HTTPS'} eq 'on' ) { | |
print "<b>This script requires HTTPS.</b>\n"; | |
die; | |
} | |
print "Logged in as <b>$ENV{REMOTE_USER}</b>. LDAP URI is <b>$host</b>.<br>\n"; | |
$cgi = new CGI::Lite; | |
%form = $cgi->parse_form_data; | |
if ($form{'op'} eq 'submit') { | |
my $user_dn = $form{'dn'}; | |
my $user_pw = $form{'oldpassword'}; | |
my $newpw1 = $form{'newpw1'}; | |
my $newpw2 = $form{'newpw2'}; | |
die 'Password mismatch.' unless ( $newpw1 eq $newpw2 ); | |
die 'No DN specified.' unless $user_dn; | |
print "Attempting to bind as <b>$user_dn</b> ... "; | |
my $mesg = $ldap->bind($user_dn, | |
password => $user_pw); | |
if ($mesg->is_error) { | |
my $err = "Error attempting to bind as $user_dn: ". $mesg->error; | |
print "<pre>$err</pre>"; | |
die $err; | |
} | |
print " OK.<br>\n"; | |
my $oldUniPW = $charmap->tou('"'.$user_pw.'"')->byteswap()->utf16(); | |
my $newUniPW = $charmap->tou('"'.$newpw1.'"')->byteswap()->utf16(); | |
print "Attempting to modify password for <b>$user_dn</b> ... "; | |
$mesg = $ldap->modify($user_dn, | |
changes => [ | |
delete => [ unicodePwd => $oldUniPW ], | |
add => [ unicodePwd => $newUniPW ] ]); | |
print "OK<br>\n"; | |
# $mesg->is_error && die ('Modify error: '. $mesg->error); | |
if ($mesg->is_error) { | |
my $err = 'Modify error: '. $mesg->error; | |
print "<pre>$err</pre>\n"; | |
die $err; | |
} | |
$ldap->unbind(); | |
print "<blink>VICTORY!!</blink> Successfully changed password for user $ENV{REMOTE_USER}, DN <b>$user_dn</b>, msg ID: ".$mesg->mesg_id ."\n"; | |
} else { | |
# bind as dummy to lookup the user's DN | |
my $mesg = $ldap->bind($bind_dn, password => $bind_pw ); | |
$mesg->is_error && die ('Bind error: '. $mesg->error); | |
$mesg = $ldap->search( | |
base => $base_dn, | |
scope => 'sub', | |
attrs => ['dn','cn','mail'], | |
filter => "(&(samaccountname=$ENV{REMOTE_USER})$search_filter)" | |
); | |
$mesg->is_error && die ( 'Search failed: '. $mesg->error ); | |
$mesg->count || die ("Search for user '$ENV{REMOTE_USER}' returned no results."); | |
my $entry = $mesg->entry( 0 ); | |
$ldap->unbind(); | |
print "LDAP DN for user '$ENV{REMOTE_USER}': <b>".$entry->dn.'</b>'; | |
print "<form action='$ENV{REQUEST_URI}' METHOD='POST'>\n"; | |
print "<input type='hidden' name='op' value='submit'>\n"; | |
print "<input type='hidden' name='dn' value='".$entry->dn."'>\n"; | |
print "<table border='0'>\n"; | |
print "<tr><td>Current password for <b>$ENV{REMOTE_USER}</b>:</td><td><input type='password' name='oldpassword' size='30'></td></tr>\n"; | |
print "<tr><td>New password for <b>$ENV{REMOTE_USER}</b>:</td><td><input type='password' name='newpw1' size='30'></td></tr>\n"; | |
print "<tr><td>New password for <b>$ENV{REMOTE_USER}</b> <i>again</i>:</td><td><input type='password' name='newpw2' size='30'></td></tr>\n"; | |
print "<tr><td colspan='2'><input type='submit' name='submit' value='Change Password'><input type='reset' value='Reset Form'></td></tr>\n"; | |
print "</form>\n"; | |
print "</table>\n"; | |
} | |
print '</body></html>'; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment