使用PHP/COM/ADSI/LDAP更改广告密码
这件事已经困扰了我好几天了。我试过各种各样的解决办法,但都没有用。请帮忙 问题:我们有两个域控制器,它们不在我们的管理之下。我们可以通过端口389上的LDAP进行连接,但无法通过端口636进行安全连接 我们正在开发一个系统,以允许一些自助服务设施,其中之一是密码恢复工具。这会导致重置用户密码 我找到了一些代码,这些代码似乎可以满足我们的需要,但似乎无法使其正常工作 这就是我到目前为止的代码使用PHP/COM/ADSI/LDAP更改广告密码,php,iis,active-directory,adsi,change-password,Php,Iis,Active Directory,Adsi,Change Password,这件事已经困扰了我好几天了。我试过各种各样的解决办法,但都没有用。请帮忙 问题:我们有两个域控制器,它们不在我们的管理之下。我们可以通过端口389上的LDAP进行连接,但无法通过端口636进行安全连接 我们正在开发一个系统,以允许一些自助服务设施,其中之一是密码恢复工具。这会导致重置用户密码 我找到了一些代码,这些代码似乎可以满足我们的需要,但似乎无法使其正常工作 这就是我到目前为止的代码 if ($caller==="change"){ if (($newPword1 === NULL)||(
if ($caller==="change"){
if (($newPword1 === NULL)||($newPword1 === "" )){ return false;}
if (($newPword2 === NULL)||($newPword2 === "" )){ return false;}
if ($newPword1 != $newPword2) {
$result["ERROR"]="1";
$result["DETAILS"]="Your new password and the confirmation must match!";
exit();
}
try {
$adldap = new adLDAP();
} catch (adLDAPException $e) {
$result["ERROR"]="1";
$result["DETAILS"]="An error occurred in adLDAP";
echo json_encode($result);
exit();
}
$userinfo = $adldap->user()->info($username, array("givenname","dn","lockouttime"));
$res = $userinfo[0]["lockouttime"];
$userDN = $userinfo[0]["dn"];
$firstName = $userinfo[0]["givenname"];
$authUser = $adldap->authenticate($username,$currentPword);
if ($authUser){
try {
$adminUsername = $domain."\\".$adminUsername;
$srvDN = "LDAP://".$server."/";
try {
$ADSI = new COM("LDAP:");
} catch (exception $e){
$result["ERROR"]="1";
$result["ERRORmsg"]=$e->getMessage();
echo json_encode($result);
exit();
}
try {
$user = $ADSI->OpenDSObject($srvDN.$userDN, $adminUsername, $adminPassword, 1);
} catch (exception $e){
$result["ERROR"]="2";
$result["ERRORmsg"]= $e->getMessage();
echo json_encode($result);
exit();
}
try { //set password
if ($user){
$result["object"]="Success";
} else {
$result["object"]="Failed";
}
$user->SetPassword($newPword1); //line:114 -> error occurring on this line
$user->SetInfo();
$result["ERROR"]="0";
$result["DETAILS"]="Thank you $firstName[0]<br><strong>Your password has been changed</strong><br><br>This may take up to 30 minutes to take effect depending on your location";
} catch (exception $e) {
$result["ERROR"]="3";
$result["ERRORmsg"]=$e." - ".$e->getMessage();
$result["DETAILS"]="An Error Occurred.";
}
unset($user);
unset($ADSI);
} catch (exception $e){
$result["ERROR"]="1";
$result["DETAILS"]="An Error Occurred in the ADSI COM";
echo json_encode($result);
exit();
}
} else {
if ($res[0] != "0"){
$result["ERROR"]="1";
$result["DETAILS"]="Im sorry $firstName[0].<br>Your account is now locked. Please contact the IT Service Desk for advice";
} else {
$result["ERROR"]="1";
$result["DETAILS"]="Im sorry $firstName[0].<br>Your current password is incorrect";
}
}
上述代码位于IIS Web服务器上的php文档中,该服务器由用户通过https访问的页面调用
您能提供任何建议或指导吗?我也在做同样的事情,现在已经开始工作了,至少在针对服务器2k8R2 DC时是这样 我不知道你为什么会失败,但我发现有两件事很有帮助: 1) 在catch()处理程序中,检索从SetPassword()返回的错误,按如下方式处理并显示它
$rawErr = $e->getCode();
$processedErr = $rawErr + 0x100000000;
printf( 'Error code 0x%x', $processedErr );
然后看看你能不能找到它。你也会发现这很有帮助
2) 尝试更改对ChangePassword()的SetPassword()调用。这要求您也输入旧密码,但对DC的权限要求不太严格。如果您能使其正常工作,则可能表明SetPassword()的问题在于您在OpenDSObject()调用中用于身份验证的管理员帐户在目标域上没有足够的权限
关于ChangePassword()的一点警告是,与SetPassword()不同,密码策略是严格执行的。因此,您需要考虑最小密码期限和复杂性,以及历史记录。最后一个问题我没有解决
祝你好运,伊恩。我发现你使用的操作系统对使用这段代码有直接影响 我在桌面上使用本地版本的IIS(Windows 7 Enterprise,IIS 7.5)进行开发工作时,一直遇到此未知错误 但是,一旦我在实际服务器(Windows)上测试了ADSI密码重置代码 服务器2008 R2),它工作完美无瑕
供参考: 我得到的错误代码(使用Ian的答案)是0x80020009,它似乎与这个问题有关:() 因此,无论出现什么问题,似乎都比ADSI和PHP/COM更深 注意:
与ChrisM一样,我能够使用ADSI连接来查询信息。只有当我尝试使用SetPassword()时,才出现故障。我确信AD对于不通过明文LDAP设置密码非常挑剔。您需要它们来启用LDAP上的SSL。您是否尝试过phpLdapAdmin?12月29日16:46更新我已经能够证明
新COM(“LDAP:”)
成功初始化并$ADSI->OpenDSObject
成功打开AD对象。我尝试过其他用户广告帐户,但脚本在同一行失败**12月29日17:57**已替换$user->SetPassword($newPword1)代码>带有$user->Put(“pwdLastSet”,0)代码>并成功更新了相应的AD属性。因此,这表明ADSI连接正在工作。是否有人知道GSS-API/Kerberos是否允许我通过绑定ldap_sasl?Hi Ian来实现这一点,谢谢您的输入。作为回应:1)我将添加额外的错误代码。从内存中返回的错误代码不在selfADSI列表中,我认为是-215。。。但我会检查并确认这一点。2) 我使用的服务帐户具有域管理员权限。一旦我让代码正常工作,这个级别将降低到对用户对象的更高权限。根据权力机构的指示,严格检查以强制执行域密码策略。我正在研究SASL/GSS-API/Kerberos解决方案。工作后将发布代码。你是怎么工作的?
$rawErr = $e->getCode();
$processedErr = $rawErr + 0x100000000;
printf( 'Error code 0x%x', $processedErr );