【发布时间】:2018-03-10 02:42:19
【问题描述】:
我们正在通过 LDAPS 连接来重置 Active Directory 用户密码。我们还设置了“下次登录时更改密码”属性。
当我们登录到 Windows 机器时,我们执行以下步骤:
- 使用新密码(密码1)登录windows机器
- 机器提示修改密码
- 输入现有密码(password 1)和新密码(password 2)
此时我们正在等待消息:Your password has been changed.You will need to use the new password for future logins。
但是我们收到消息:Unknown user name or bad password.
但是,在后端,系统已经接受了新密码(password 2),因为我们可以使用 password 2 登录。
当系统接受新密码时,我们无法理解为什么我们会收到不正确的消息
我们是否需要设置另一个属性来显示正确的消息?
我们的代码如下:
#!/usr/bin/perl -w
#########################
#This script resets the password in active user directory
#########################
use strict;
use warnings;
use DBI;
use Net::LDAP;
use Net::LDAPS;
use Authen::SASL qw(Perl);
use Net::LDAP::Control::Paged;
use Time::Local;
use MIME::Lite;
my $CERTDIR = "<certpath>";
my $AD_PASS = "$CERTDIR/<certfile>";
my $sAN = $ARGV[0];
my $uninewpass;
my $mail;
my $fullname;
my $name;
my $distName;
my $finalresult;
### Generate Random Password ###
my $randompass = askPasswd();
### Reading Active directory connection credentials ###
my @AD_passwords = get_domain_pass();
###Reset password###
my $result = reset_AD_Password();
###SUB FUNCTIONS###
#Reset AD user password
sub reset_AD_Password {
my $result = "fail";
my $ad = Net::LDAPS->new($AD_passwords[0]);
my $msg = $ad->bind(dn => "cn=$AD_passwords[2],$AD_passwords[1]",
password => $AD_passwords[3],
version => 3);
if ($msg->code)
{
print "Error msg:" . $msg->error() . "\n";
print "Error code:" . $msg->code() . "\n";
exit 3;
}
my $acc_name = 'sAMAccountName';
my $acc_fullname = 'displayName';
my $acc_distName = 'distinguishedName';
my $acc_mail = 'mail';
my $act = $ad->search(
base => "$AD_passwords[1]",
filter => "(&(objectCategory=person)(sAMAccountName=$sAN))",
attrs => [$acc_name, $acc_fullname, $acc_distName, $acc_mail]);
die 2 if ($act->count() !=1 );
if ($act->code)
{
print "Error msg:" . $act->error() . "\n";
print "Error code:" . $act->code() . "\n";
exit 4;
}
#Store DN for password reset
my $sANdn = $act->entry(0)->dn;
# Add quotes and uniCode to the passwords.
map { $uninewpass .= "$_\000" } split(//, "\"$randompass\"");
print "$uninewpass\n";
#Reset AD Password and change at next logon
my $rtn = $ad->modify($sANdn, replace => [ 'unicodePwd' => $uninewpass]);
if($rtn->{'resultCode'} != 0) {
print "Error msg:" . $rtn->error() . "\n";
print "Error code:" . $rtn->code() . "\n";
exit 5;
}
#Change Password at next logon#
my $rtn = $ad->modify($sANdn, replace => { pwdLastSet => 0});
if($rtn->{'resultCode'} != 0) {
print "Error msg:" . $rtn->error() . "\n";
print "Error code:" . $rtn->code() . "\n";
exit 6;
}
$result = "pass";
return $result;
}
###Generate password###
sub askPasswd {
use String::Random;
my $randPass = new String::Random;
my $rndpassword = $randPass->randpattern("CCccn!cnC");
print "Your random password is: " , $rndpassword , "\n";
return $rndpassword;
}
###Read Credentials File###
sub get_domain_pass {
open(my $fh, '<:encoding(UTF-8)', $AD_PASS) or die "Could not open file";
my $row = <$fh>;
chomp $row;
print "$row\n";
my @AD_passwords = split/:/,$row;
return @AD_passwords;
}
【问题讨论】:
-
您是否考虑过选择其中一些变量?测试代码很困难,因为我没有相同的场景,所以在这里半夜刺伤。
-
另外,您是否希望
Your password has been changed.You will need to use the new password for future logins消息来自 AD? -
@GerhardBarnard perl 代码工作得很好。它正确地创建了 密码 1。您建议使用哪些变量
chomping是的,当提示用户更改密码时,我们希望来自 AD 的Your password has been changed.You will need to use the new password for future logins消息
标签: perl active-directory ldap