PHP Conference Japan 2024

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"中的正确
域名,例如,如果您的域名是phpfreackx.com,则为"DC=phpfreackx,DC=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出现令人困惑的“类型或值已存在”错误,原因可能是您试图为多值属性添加两个相同的值。例如:

<?php
$le
= array("mail" => array("[email protected]", "[email protected]"));
$result = ldap_modify($ldap_link, $dn, $le);
?>
0
jmw1982 at gmail dot com
19年前
如果您使用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
21年前
如果您尝试使用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

例如,如果您有一个类型为“device”(一个结构化objectclass)的ldap条目,名为“cn=myNetCard,ou=Networks,dc=example,dc=com”,您可以这样做

<?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);
?>

您将收到以下错误:“无法修改对象类”
-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中,您将收到“无效语法”错误,并且修改失败。

这需要使用 `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
[email protected]
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
匿名用户
9 年前
在尝试将用户添加到 Active Directory 中的用户组时,我遇到一个相当烦人的问题。

当尝试修改“memberOf”属性(通过 `ldap_mod_add`/`ldap_mod_replace`)时,Active Directory 往往不太高兴,并且会在某个地方输出警告/错误,例如:

警告:`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
[email protected]
11 年前
如果你无法使用 `ldap_modify` 向现有对象添加属性 `objectclass` - 使用 `ldap_mod_add` - 它可以工作。
-4
匿名用户
9 年前
在尝试将用户添加到 Active Directory 中的用户组时,我遇到一个相当烦人的问题。

当尝试修改“memberOf”属性(通过 `ldap_mod_add`/`ldap_mod_replace`)时,Active Directory 往往不太高兴,并且会在某个地方输出警告/错误,例如:

警告:`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