我已经被这几天困住了。我尝试了各种解决方案无济于事。请帮忙......
问题:我们有两个域控制器,不在我们的管理之下。我们可以通过端口389上的LDAP进行连接,但无法通过端口636进行安全连接。
我们正在开发一个允许许多自助服务设施的系统,其中一个是密码恢复工具。这样做可以重置用户密码。
我找到了一些代码via the PHP manual似乎可以满足我们的需要,但似乎无法让它发挥作用。
这是我到目前为止的代码
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";
}
}
在测试中$result["object"]
返回“成功”。但代码似乎在$user->SetPassword($newPword1);
行上失败了。
返回的错误是:
ERROR -> "3"
object -> "Success"
ERRORmsg -> "exception 'com_exception' with message '<b>Source:</b> Unknown<br/><b>Description:</b> Unknown' in C:\inetpub\wwwroot\<path>\<filename>.php:114
Stack trace:
#0 C:\inetpub\wwwroot\<path>\<filename>.php(114): variant->SetPassword('P@ssw0rd')
#1 {main} - <b>Source:</b> Unknown<br/><b>Description:</b> Unknown"
DETAILS -> "An Error Occurred."
以上代码位于IIS Web服务器上的php文档中,由https上的用户可查看页面调用
您能提供任何建议或指导吗?
答案 0 :(得分:1)
我做了几乎相同的事情,现在让它工作,至少在针对服务器2k8R2 DC时。
我不确定你为什么会失败,但我发现有些事情是有帮助的:
1)在catch()处理程序中检索从SetPassword()返回的错误,处理并显示如下
$rawErr = $e->getCode();
$processedErr = $rawErr + 0x100000000;
printf( 'Error code 0x%x', $processedErr );
然后看看你是否可以找到here列出的内容。您可能还会发现this有帮助。
2)尝试改变对ChangePassword()的SetPassword()调用。这要求您输入旧密码,但对DC的权限要求不那么严格。如果你可以让它工作,它可能表明你的SetPassword()问题是你在OpenDSObject()调用中用于验证的管理员帐户在目标域上没有足够的权限。
关于ChangePassword()的警告,与SetPassword()不同,严格执行密码策略。因此,您需要考虑最小密码年龄和复杂性以及历史记录等内容。我最后一次失败了。
非常好运,Ian。
答案 1 :(得分:0)
我发现您使用的操作系统对使用此代码有直接影响。
我使用本地版本的IIS(Windows 7企业版,IIS 7.5)在桌面上进行开发工作,并一直遇到此未知错误。
然而,一旦我在实际服务器上测试了我的ADSI密码重置代码(Windows Server 2008 R2),它完美无缺。
供参考: 我得到的错误代码(使用伊恩的答案)是0x80020009,这似乎与这个问题有关:(Registering a dll returns 0x80020009 error)
所以出现问题似乎比ADSI和PHP / COM更深。
注意:强> 像ChrisM一样,我能够使用ADSI连接查询信息,只有在我尝试使用SetPassword()时才会发生故障