From: Christopher A B. <ca...@tc...> - 2002-04-24 15:34:37
|
As Jim Harle once put it so eloquently: > Does anyone have a code snippet of changing passwords in Active Directory > via Net::LDAP? From what I can gather, you need 1) to have 128 bit SSL > connection 2) have either old and new password or be bound with Reset > Password rights and 3) put things out correctly for changing the > unicodePwd attribute. I am unsure as to how to use an old password (is it > part of a modify or do we need to bind with it?) and how to format the new > password correctly for unicodePwd. This is how you can do it if you are bound via LDAPS with sufficient (administratorish?) rights. I've never tried to do this as a user changing their own password (our AD is slaved to our X.500 directory, so all changes come from X.500 via the script from which this was taken). But this shows you how you can format unicodePwd so that AD will take the change. &change_changes is there because when you do a "replace" on an attribute of an Entry object, it adds a "replace" action to the entry rather than modifying an existing "replace" command, which would result in AD trying to modify unicodePwd twice; once with the original (plaintext) value, and once with the "fixed" version. The first modify would cause an error that would cause the whole operation to be rejected. So we have to dig a little in the actual Entry structure. If you're not reusing an existing Entry object (i.e. you're building one from scratch) or you're directly updating the entry, the change_changes bit isn't necessary. # done; now, if there's still a unicodePwd, then UTF-16(?) it # and base64 encode it and make sure it gets sent that way. my $opw = $entry->get_value('unicodePwd'); if (defined $opw) { my $upw = pack "v*", unpack "C*", qq("$opw"); &change_changes($entry, 'replace', 'unicodePwd', $upw); } sub change_changes { my ($entry, $op, $attr, @values) = @_; # add/delete entry operations don't have this problem # so just use the regular method to update them unless ($entry->changetype eq 'modify') { $entry->$op($attr, \@values); return; } # ok, this is a modify, do it the hard way $attr = lc $attr; my $changes = $entry->{changes}; for (my $i = 0; $i < @$changes; $i += 2) { my ($oldop, $oldargs) = @{$changes}[$i, $i+1]; my ($oldattr, $oldvals) = @$oldargs; if ($oldattr eq $attr) { $changes->[$i] = $op; $oldargs->[1] = \@values; last; } } } %% Christopher A. Bongaarts %% ca...@tc... %% %% Internet Services %% http://umn.edu/~cab %% %% University of Minnesota %% +1 (612) 625-1809 %% |