We use a modify/replace on the dn to change the password. However, this operation will only succed over LDAPS and not over LDAP. Here's a sub that we use in our account maint 'system' to change AD passwords: sub _setADPasswordForUser { my ($dn, $pass) = @_; my $name = "_setADPasswordForUser"; my ( $package, $filename, $line ) = caller; debug("$name: entering with args @_"); debug("$name: called from package->$package, filename->$filename, line->$line"); my $retval = 0; my $npass; my $ad = _adConnect(); map { $npass .= "$_\000" } split(//, "\"$pass\""); debug("$name: unicodePwd => $npass"); my $rtn = $ad->modify($dn, replace => { "unicodePwd" => $npass }); if ( $rtn->code ) { logmsg("$name: FAILED to change password for $dn"); logmsg("$name: LDAP error code is: " . $rtn->code); logmsg("$name: LDAP error text is: " . $rtn->error); } else { $retval = 1; } _adClose($ad); return($retval); }
In this one, _adConnect() flips through 3 win2k3 DC's and hits the first one it finds that the connect succeeds on. When those were defined as LDAP it didn't work, when we installed certs and went to SSL it all started working. Also, the dn that's used to bind in _adConnect is a domain admin account, but it's not *the* admin account (it's disabled). I've had this particular code in production since June of last year and it's changed many many thousands of passwords. Oh, and note that this runs on a Solaris 8 system using Perl 5.8.something. > Strangely, if I use a "replace" operation instead of changes=>{delect,add}, > it is accepted (tho i gotta bind as an admin user as well). Doesn't seem to > be a permission issue, as that would show up differently (such as using > "replace" without being an admin). What else could it be ? AD requires that you use replace, not delete/add, for userPassword. It's Just The Way It Is.