Note, in the first line, that we're connecting over SSL. Active Directory requires an SSL connection in order to update passwords.\n\n{{{\n$this->ad_handle = ldap_connect("ldaps://activedirectoryserver.hostname", 636);\n$r = @ldap_set_option($this->ad_handle , LDAP_OPT_PROTOCOL_VERSION, 3);\n$r = @ldap_bind($this->ad_handle, "<ldap bind dn>", "<ldap bind password>");\n}}}
<<<\nThe password is stored in the Active Directory on a user object in the unicodePwd attribute. This attribute can be written under restricted conditions, but it cannot be read. The attribute can only be modified; it cannot be added on object creation or queried by a search. In order to modify this attribute, the client must have a 128-bit Secure Socket Layer (SSL) connection to the server. For this connection to be possible, the server must possess a server certificate for a 128-bit RSA connection, the client must trust the certificate authority (CA) that generated the server certificate, and both client and server must be capable of 128-bit encryption.\n\nThe syntax of the unicodePwd attribute is octet-string; however, the directory service expects that the octet-string will contain a UNICODE string (as the name of the attribute indicates). This means that any values for this attribute passed in LDAP must be UNICODE strings that are ~BER-encoded (Basic Encoding Rules) as an octet-string. In addition, the UNICODE string must begin and end in quotes that are not part of the desired password.\n\nThere are two possible ways to modify the unicodePwd attribute. The first is similar to a normal "user change password" operation. In this case, the modify request must contain both a delete and an add operation. The delete operation must contain the current password with quotes around it. The add operation must contain the desired new password with quotes around it.\n\nThe second way to modify this attribute is analogous to an administrator resetting a password for a user. In order to do this, the client must bind as a user with sufficient permissions to modify another user's password. This modify request should contain a single replace operation with the new desired password surrounded by quotes. If the client has sufficient permissions, this password become the new password, regardless of what the old password was.\n\n(Source: Microsoft Knowledge Base document #269190)\n<<<\n\n(The code samples linked below use the second (administrator reset) method referenced in the MS article.)\n\nActiveDirectoryPasswordChangesPHP\nActiveDirectoryPasswordChangesPerl\n\n
The below code assumes that an ldap connection to Active Directory is already established (ActiveDirectoryConnectPHP), with the connection handle stored in $this->ad_handle, and bound as a user that has setpassword rights.\n\n{{{\nfunction set_password($username, $password) {\n $retval = 0;\n $dn = $this->get_ldap_dn($username);\n\n $newpassword = "$password";\n $newpassword = "\s"" . $newpassword . "\s"";\n $len = strlen($newpassword);\n for ($i = 0; $i < $len; $i++) $newpass .= "{$newpassword{$i}}\s000";\n $entry["unicodePwd"] = $newpass;\n\n $logfile = fopen ("./passwordchange_log.txt", "a+");\n $logline = date("Y-m-d H:i:s") . " - password for account " . $username . " changed by " . $GLOBALS['REMOTE_USER'] . "\sn";\n fwrite($logfile, $logline);\n fclose ($logfile);\n\n if ($this->has_letnet_account) {\n if (ldap_mod_replace($this->ad_handle, $dn, $entry)) {\n $retval = 1;\n print "<p align=\s"center\s">AD Password change succeeded!</p>";\n } else {\n print "<p align=\s"center\s">AD Password change failed.</p>";\n }\n }\n return ($retval);\n}\n}}}
Uses the Net::LDAPS library. Microsoft requires an SSL connection to your Active Directory server in order to update passwords. This code uses two separate connections to Active Directory -- one which does searches, and one which makes updates only. This is probably not strictly necessary.\n\n{{{\nsub set_password($,$) {\n my ($username, $password) = @_;\n my ($Ad_write, $Ad_read, $mesg, $npass, $dn, $rtn);\n\n if (($username eq '') or ($password eq '')) {\n print "Uid and/or password missing in input\sn";\n return 0;\n }\n\n # Bind to the AD server\n\n $Ad_write = Net::LDAPS->new("activedirectoryserver.hostname", version => 3) or print "Unable to connect to account database server (writer)\sn", return 0;\n $Ad_read = Net::LDAPS->new("activedirectoryserver.hostname", version => 3) or print "Unable to connect to account database server (reader)\sn", return 0;\n $Ad_write->bind(dn => "<ldap bind dn>", password => "<ldap bind password>") or print "Unable to bind to account database server (writer)\sn", return 0;\n $Ad_read->bind(dn => "<ldap bind dn>", password => "<ldap bind password>") or print "Unable to bind to account database server (reader)\sn", return 0;\n\n # Do a AD lookup to get the dn for this user\n # then change their password.\n\n $mesg = $Ad_read->search(base => "ou=accounts, dc=letnet, dc=net", filter => "cn=$username");\n if($mesg->count != 1) {\n print "Didn't find a valid account for user $username\sn";\n print $mesg->count . "\sn";\n return 0;\n }\n\n # Add quotes and uniCode\n map { $npass .= "$_\s000" } split(//, "\s"$password\s"");\n\n # Now change it\n $dn = $mesg->entry(0)->dn;\n\n $rtn = $Ad_write->modify($dn, replace => { "unicodePwd" => $npass });\n if($rtn->{'resultCode'} != 0) {\n print "User $username, setting password failed: " . $rtn->{'resultCode'} . "\sn";\n return 0;\n }\n\n print p, "Password for $username successfully changed.";\n\n return 1\n}\n}}}
/***\n|''Name:''|LegacyStrikeThroughPlugin|\n|''Description:''|Support for legacy (pre 2.1) strike through formatting|\n|''Version:''|1.0.1|\n|''Date:''|Jul 21, 2006|\n|''Source:''||\n|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|\n|''License:''|[[BSD open source license]]|\n|''CoreVersion:''|2.1.0|\n|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|\n\n***/\n\n//{{{\n\n// Ensure that the LegacyStrikeThrough Plugin is only installed once.\nif(!version.extensions.LegacyStrikeThroughPlugin)\n {\n version.extensions.LegacyStrikeThroughPlugin = true;\n\nconfig.formatters.push(\n{\n name: "legacyStrikeByChar",\n match: "==",\n termRegExp: /(==)/mg,\n element: "strike",\n handler: config.formatterHelpers.createElementAndWikify\n});\n\n} // end of "install only once"\n//}}}\n
[[Overview|ActiveDirectoryPasswordChanges]]\n[[Perl Code|ActiveDirectoryPasswordChangesPerl]]\n[[PHP Code|ActiveDirectoryPasswordChangesPHP]]
code samples in Perl and PHP
Changing Active Directory passwords