ldap_modify

(PHP 4, PHP 5, PHP 7, PHP 8)

ldap_modifyldap_mod_replace() 的别名

描述

此函数是 ldap_mod_replace() 的别名。

参见

添加备注

用户贡献的备注 16 个备注

3
ace at suares dot nl
20 年前
关于 ldap_modify 的一些评论,尤其是 tengel at fluid dot com 的用户评论

OpenLDAP 2.1.22
如果属性在模式中被标记为 MUST,则必须存在该属性。是否可以包含空值取决于该属性的语法。

DirectoryString 不能为 空;OctetString 可以为 空。据我所知,IA5String 不能为 空。

如果属性在模式中定义为 MAY,则该属性可以存在也可以不存在。如果它存在,则可以为空,也可以不为空,具体取决于它的语法。

PHP 4.3.1

看来 ldap_modify() 可以接受一个要修改的属性数组。

对于多值属性,传递一个空数组将删除该属性,无论它的先前值是什么,也不管该属性之前是否存在。

如果多值属性被定义为 MAY,这将有效。如果属性被定义为 MUST,OpenLDAP 将生成错误:'LDAP error 65: Object class violation'

如果属性的语法定义它不能为空,则尝试使用空值添加或修改该属性将生成错误:'LDAP error 21: Invalid syntax'。
此外,在日志文件中,如果使用足够的调试级别设置,字符串

value #0 invalid per syntax

将存在。

尝试为任何属性(多值或单值)传递一个空数组到 ldap_add() 将导致错误 'LDAP error 2: Protocol error',无论该属性是否被定义为 MUST 或 MAY。

请注意,这与传递一个具有没有值的元素的数组不同。在后一种情况下,它取决于该属性的语法是否允许。

如果属性是单值的,传递一个包含一个元素的数组将更改属性的值。在 php.net 上的用户评论中,建议如果要修改单值属性,必须传递一个字符串,而不是一个包含一个元素的数组。我的经验是,一个包含一个元素的数组也可以正常工作。

_Ace

网站:http://www.suares.nl * http://www.qwikzite.nl
4
chris at uffbasse dot de
20 年前
为了查明删除问题

使用较新的 OpenLdap 版本,这将失败

$values["mail"] = "";
ldap_modify($conn_id, $dn, $values);

或者
$values["mail"][0] = "";
ldap_modify($conn_id, $dn, $values);

但这个有效

$values["mail"] = array();
ldap_modify($conn_id, $dn, $values);

或者
$values["mail"][0] = array();
ldap_modify($conn_id, $dn, $values);
2
docwoelle at ipwatch dot de
18 年前
如果你想在 Windows 的 Active Directory 中禁用一个帐户,
你可以试试这个(它在我的 Win2k 环境中有效)

(foo.bar 应该在 "$ldapBase" 中替换为正确的
域,例如 "DC=phpfreackx,DC=com",如果你的域是 phpfreackx.com)

domctrl = 域控制器
domadlogin = 域管理员登录
domadpw = 域管理员密码
username = 用户帐户的登录名(例如 "john.doe")
enable = 1(如果你想启用它,0 如果它应该被禁用)

<?php
function userchange($username,$enable=1,$domadlogin,$domadpw,$domctrl)
{
$ldapServer = $domctrl;
$ldapBase = 'DC=foo,DC=bar';
$ds = ldap_connect($ldapServer);
if (!
$ds) {die('无法连接到 LDAP 服务器');}
$ldapBind = ldap_bind($ds,$domadlogin,$domadpw);
if (!
$ldapBind) {die('无法绑定到 LDAP 服务器');}
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
$sr = ldap_search($ds, $ldapBase, "(samaccountname=$username)");
$ent= ldap_get_entries($ds,$sr);
$dn=$ent[0]["dn"];
// 禁用
$ac = $ent[0]["useraccountcontrol"][0];
$disable=($ac | 2); // 设置所有位加上位 1 (=dec2)
$enable =($ac & ~2); // 设置所有位减去位 1 (=dec2)
$userdata=array();
if (
$enable==1) $new=$enable; else $new=$disable; //启用或禁用?
$userdata["useraccountcontrol"][0]=$new;
ldap_modify($ds, $dn, $userdata); //更改状态
$sr = ldap_search($ds, $ldapBase, "(samaccountname=$username)");
$ent= ldap_get_entries($ds,$sr);
$ac = $ent[0]["useraccountcontrol"][0];
if ((
$ac & 2)==2) $status=0; else $status=1;
ldap_close($ds);
return
$status; //返回当前状态(1=启用,0=禁用)
}

// 使用此函数禁用帐户:
// userchange('[email protected]',0,'[email protected]', 'secret','domctrl.foo.bar');
// ..但是这样启用它:
// userchange('[email protected]',1,'[email protected]', 'secret','domctrl.foo.bar');
?>
1
goetz at rvs dot uni-hannover dot de
21 年前
请记住,您不能使用 ldap_modify 修改 'objectclass' 属性!

如果您使用搜索结果作为更改的基础,请确保 'unset()' 所有编号索引、'count' 索引以及索引 'objectclass'!
0
kevin at guarana dot org
17 年前
如果您看到来自 ldap_modify 的令人困惑的 "Type or value exists" 错误,原因可能是您试图为多值属性添加两个相同的值。例如,类似于

<?php
$le
= array("mail" => array("[email protected]", "[email protected]"));
$result = ldap_modify($ldap_link, $dn, $le);
?>
0
jmw1982 at gmail dot com
18 年前
如果您正在使用 ldap_modify() 为属性写入多个值,该函数将尝试写入值数组中的所有条目,即使这些条目为空。将空条目设置为用于属性删除的空数组,即

$attributes[$attr_name][3] = array ();

导致字符串 "Array" 被写入该值的目录。我发现的唯一方法可以做到我想要的 - 只写入表单提交的属性值 - 是检查每个属性是否具有多个值,并取消设置() 空值,例如

foreach ($attributes as $key => $cur_val) {
if ($cur_val== '') {
$attributes[$key] = array ();
}
if (is_array ($cur_val)) {
foreach ($cur_val as $mv_key => $mv_cur_val) {

if ($mv_cur_val == '') {
unset ($attributes[$key][$mv_key]);
}
else {
$attributes[$key][$mv_key] = $mv_cur_val;
}
}
}
}
0
fechner at ponton dot de
20 年前
如果您尝试在使用 md5 哈希时更改 userPassword 属性,请尝试以下几行

$new["userPassword"] = '{md5}' . base64_encode(pack('H*', md5($newpass_in_plaintext)));
ldap_modify($ds, $dn, $new);
0
davidsmith at byuNOSPAM dot edu
21 年前
$entry 参数可以是属性值的数组。请注意,您的数组索引必须是连续的数字。例如,当使用此 $entry 数组时,ldap_modify 将失败,几乎没有解释

$entry = array( 0 => 'foo', 2 => 'bar' );

而这个可以正常工作

$entry = array( 0 => 'foo', 1 => 'bar' );

希望这对某人有所帮助。
0
jpdalbec at ysu dot edu
21 年前
Nick T. 的上面评论已经过时。
PHP LDAP 接口目前支持使用 ldap_rename() 函数直接修改 DN。
-1
php_notes at grumz dot net
17 年前
继 goetz at rvs dot uni-hannover dot de 的评论之后,ldap_modify 不能更改 objectclass 并不完全正确。

事实上,不可能添加在模式描述中设置为 STRUCTURAL 的 objectclass。但您可以添加设置为 AUXILIARY 的 objectclass。请参阅下面的 OpenLDAP 常见问题解答,了解原因

http://www.openldap.org/faq/data/cache/1341.html

例如,如果您有一个名为 "cn=myNetCard,ou=Networks,dc=example,dc=com" 的类型为 "device" 的 ldap 条目,它是一个结构化 objectclass,您可以执行以下操作

<?php

$entry
["objectclass"][0] = "device";
$entry["objectclass"][1] = "ieee802Device"; // 添加辅助 objectclass
$entry["macAddress"][0] = "aa:bb:cc:dd:ee:ff";

ldap_modify ($cnx, "cn=myNetCard,ou=Networks,dc=example,dc=com", $entry);
?>

但这不会起作用

<?php

$entry
["objectclass"][0] = "device";
$entry["objectclass"][1] = "ipNetwork"; // 添加结构化 objectclass
$entry["ipNetworkNumber"][0] = "1.2.3.4";

ldap_modify ($cnx, "cn=myNetCard,ou=Networks,dc=example,dc=com", $entry);
?>

您将收到以下错误:"Cannot modify object class"
-1
NOSPAMjjhuff at mspin dot net
22 年前
要删除条目

$data["description"] = array();
ldap_modify($conn, $dn,$data);
-1
tengel at fluid dot com
23 年前
OpenLDAP 从 1.x 到 2.x 的行为发生了变化;在 1.x 中,当您将数组传递给 ldap_modify 时,如果值为空,则该属性将被删除。在 2.x 中,您会收到一个 "Invalid Syntax" 错误,修改将失败。

这需要 ldap_mod_del 函数;不幸的是,该操作需要被删除的属性指定其 *旧* 值 - 正如您可以想象的那样,如果您从 CGI 表单获取输入,则要删除的属性的值现在丢失了(即,用户在表单中清空了该文本框并单击提交)。

所以,您陷入了困境 - 您想删除 "空" 表单值,但您需要它们的旧值才能删除它们。有很多方法可以解决这个问题,但我选择了这种方法

<?php
// 第一个是添加的内容,第二个是删除的内容
$entry=array();
$delval=array();

// 想象一下,$o 和 $title 是
// 带有文本框的表单字段
if($o!="") { $entry["o"]="$o"; } else { $delval[]="o"; }
if(
$title!="") { $entry["title"]="$title"; } else { $delval[]="title"; }

// 首先尝试使用 $entry 进行正常的修改
// $ldap, $dn, $BASEDN 都在前面设置了
if (@ldap_modify($ldap, $dn, $entry)) {
// 然后进行脏活
$filter = sprintf("(&(uid=%s)(sn=%s))",$uid,$sn);
$sres = ldap_search($ldap, $BASEDN, $filter, $delval);
$delent = ldap_first_entry($ldap, $sres);
$delarr = ldap_get_attributes($ldap, $delent);
$findel=array();
for(
$i=0; $i<$delarr["count"]; $i++) {
$attr = $delarr[$i];
$totl = $delarr[$attr]["count"];
for(
$z=0; $z<$totl; $z++) {
if (
$totl = 1) {
$findel[$attr]=$delarr[$attr][$z];
} else {
$findel[$attr][$z]=$delarr[$attr][$z];
}
}
}
if(@
ldap_mod_del($ldap, $dn, $findel)) {
print(
"<H3>已修改条目!</H3>\n");
print(
"<BR>\n");
} else {
$error=ldap_error($ldap);
print(
"<H3>属性删除失败!</H3>\n");
print(
"<BR>\n($error)\n");
}
} else {
$error=ldap_error($ldap);
print(
"<H3>修改失败!</H3>\n");
print(
"<BR>\n($error)\n");
}
?>
-1
nickt at powys dot gov dot uk
25 年前
使用 ldap_modify() 修改现有的 LDAP 信息

链接标识符必须来自对服务器的连接调用,该服务器具有更新条目的权限,通常需要经过身份验证的绑定 - 也就是说,您在 ldap_bind() 调用中提供合适的 dn 和密码。

dn 必须是 LDAP 服务器上存在的单个特定 dn。LDAP 中没有通配符机制来全局更改多个 dn 条目。

条目数组必须采用两种不同的形式之一,这取决于是否只为特定属性存储一个条目,还是为该属性存储多个条目。

如果要为一个属性存储一个条目 - 例如,只存储一个电子邮件地址 - 那么您使用一般形式

<?php $newinfo[ <attribute_name> ]="whatever" ; ?>

例如 ...

<?php $newinfo["mail"]="[email protected]" ; ?>

如果要为一个属性存储多个条目 - 例如,为一个人存储多个电子邮件地址 - 那么您使用一般形式

<?php
$newinfo
[ <attribute_name> ][0] = "whatever" ;
$newinfo[ <attribute_name> ][1] = "another" ;
?>

例如 ...

<?php
$newinfo
["mail"][0]="[email protected]" ;
$newinfo["mail"][1]="[email protected]" ;
?>

有关 ldap_modify() 的进一步说明

修改调用不会改变所有其他属性的条目。因此,如果您只想更新“mail”属性的条目,那么只需要

<?php
$newinfo
[mail]="[email protected]";
ldap_modify($valid_ldaplink, $valid_dn, $newinfo);
?>

但是,如果在运行上述代码时 LDAP 数据库中存在“mail”属性的多个条目,那么所有现有的“mail”条目将被删除并被单个“mail”条目替换。

如果您有理由预期某个属性有多个值(例如,多个电子邮件条目),您应该确保首先从 ldap 服务器读取所有条目,然后保存修改后的数组。

PHP LDAP 接口目前不支持直接修改 dn。如果需要更改 dn,唯一的选择是读取 dn 的所有条目,并将这些条目保存到新的修改后的 dn,然后删除原始 dn 的完整条目。
-2
Anonymous
9 年前
我在尝试将用户添加到 Active Directory 的用户组时遇到了一个相当烦人的问题。

Active Directory 往往不喜欢您尝试修改“memberOf”属性(通过 ldap_mod_add/ldap_mod_replace),并且会在某个地方输出警告/错误,例如

警告:ldap_mod_add():修改:服务器不愿执行...

如果您想将用户添加到用户组,您需要将用户添加为该组的成员,而不是添加到该组的 memberOf 属性中

<?php
function ldap_addToGroup($username, $group) {
$dn = "CN=$group,OU=Accounts,DC=DC1,DC=DC2"; // 要添加到的组的识别名称/DN
$info["member"] = "CN=$username,OU=Accounts,DC=DC1,DC=DC2"; // 要添加的用户的 DN
return ldap_modify($ldapconn, $dn, $info);
}
?>

希望这对某人有所帮助。
-3
spam at bilgoraj dot info
11 年前
如果您无法使用 ldap_modify 将 objectclass 属性添加到现有对象 - 请使用 ldap_mod_add - 它有效。
-4
Anonymous
9 年前
我在尝试将用户添加到 Active Directory 的用户组时遇到了一个相当烦人的问题。

Active Directory 往往不喜欢您尝试修改“memberOf”属性(通过 ldap_mod_add/ldap_mod_replace),并且会在某个地方输出警告/错误,例如

警告:ldap_mod_add():修改:服务器不愿执行...

如果您想将用户添加到用户组,您需要将用户添加为该组的成员,而不是添加到该组的 memberOf 属性中

<?php
function ldap_addToGroup($username, $group) {
$dn = "CN=$group,OU=Accounts,DC=DC1,DC=DC2"; // 要添加到的组的识别名称/DN
$info["member"] = "CN=$username,OU=Accounts,DC=DC1,DC=DC2"; // 要添加的用户的 DN
return ldap_modify($ldapconn, $dn, $info);
}
?>

希望这对某人有所帮助。
To Top