ldap_add

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

ldap_add向 LDAP 目录添加条目

描述

ldap_add(
    LDAP\Connection $ldap,
    string $dn,
    array $entry,
    ?array $controls = null
): bool

在 LDAP 目录中添加条目。

参数

ldap

一个 LDAP\Connection 实例,由 ldap_connect() 返回。

dn

LDAP 实体的识别名称。

entry

一个数组,指定有关条目的信息。条目中的值由各个属性索引。如果一个属性有多个值,则使用从 0 开始的整数索引它们。

<?php
$entry
["attribute1"] = "value";
$entry["attribute2"][0] = "value1";
$entry["attribute2"][1] = "value2";
?>

controls

要与请求一起发送的 LDAP 控制 数组。

返回值

成功时返回 true,失败时返回 false

变更日志

版本 描述
8.1.0 ldap 参数现在需要一个 LDAP\Connection 实例;以前,需要一个有效的 ldap link 资源
8.0.0 controls 现在可以为空;以前,它默认为 []
7.3.0 添加了对 controls 的支持

示例

示例 #1 带有身份验证绑定的完整示例

<?php
$ds
= ldap_connect("localhost"); // 假设 LDAP 服务器在此主机上

if ($ds) {
// 使用适当的 dn 绑定以提供更新访问权限
$r = ldap_bind($ds, "cn=root, o=My Company, c=US", "secret");

// 准备数据
$info["cn"] = "John Jones";
$info["sn"] = "Jones";
$info["objectclass"] = "person";

// 将数据添加到目录
$r = ldap_add($ds, "cn=John Jones, o=My Company, c=US", $info);

ldap_close($ds);
} else {
echo
"无法连接到 LDAP 服务器";
}
?>

注释

注意: 此函数是二进制安全的。

参见

添加注释

用户贡献的注释 23 个注释

5
stian
16 年前
此解决方案对我们有效。
在表单中,CN 和 pwdtxt 是根据严格规则随机生成的。
此脚本每天在 AD 中创建 50-60 个用户!并且从未出现过故障!

<?php
## 来自表单
$CN = $_POST['CN'];
$givenName = $_POST['givenName'];
$SN = $_POST['SN'];
$mail = $_POST['mail'];
$Phone = $_POST['Phone'];
$pwdtxt = $_POST['pwdtxt'];

$AD_server = "localhost:390"; // 本地 Stunnel --> http://www.stunnel.org/
$AD_Auth_User = "[email protected]"; // 管理员用户
$AD_Auth_PWD = "duppiduppdupp"; // 密码

$dn = 'CN='.$CN.',OU=Brukere,DC=student,DC=somwhere,DC=com';

## 创建 Unicode 密码
$newPassword = "\"" . $pwdtxt . "\"";
$len = strlen($newPassword);
$newPassw = "";

for(
$i=0;$i<$len;$i++) {
$newPassw .= "{$newPassword{$i}}\000";
}

## 连接到 AD
$ds = ldap_connect($AD_server);
if (
$ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // 重要
$r = ldap_bind($ds, $AD_Auth_User, $AD_Auth_PWD); // 绑定

$ldaprecord['cn'] = $CN;
$ldaprecord['givenName'] = $givenName;
$ldaprecord['sn'] = $SN;
$ldaprecord['objectclass'][0] = "top";
$ldaprecord['objectclass'][1] = "person";
$ldaprecord['objectclass'][1] = "organizationalPerson";
$ldaprecord['objectclass'][2] = "user";
$ldaprecord['mail'] = $mail;
$ldaprecord['telephoneNumber'] = $Phone;
$ldaprecord["unicodepwd"] = $newPassw;
$ldaprecord["sAMAccountName"] = $CN;
$ldaprecord["UserAccountControl"] = "512";
// 这将防止用户被禁用。-->
http://support.microsoft.com/default.aspx?scid=kb;en-us;305144

$r = ldap_add($ds, $dn, $ldaprecord);

} else {
echo
"无法连接到 LDAP 服务器 $AD_server.";
}

?>

这是在 AD 中创建用户的代码示例。
我们在内部网页上使用它来创建
可以访问无线网络的临时用户。
我们有一个 .pl 脚本,在 24 小时后删除用户。
5
damien at groovey dot com
17 年前
以下是使用哈希 MD5 密码向 OpenLDAP 添加用户的步骤。我使用此技术将 Drupal 帐户迁移到 OpenLDAP,以实现单点登录解决方案。

诀窍是在密码之前告诉 OpenLDAP 哈希类型(例如 {MD5}),并将二进制哈希结果进行 Base64 编码。你不能直接对 PHP 的 md5() 或 sha() 哈希函数返回的结果进行 Base64 编码,因为它们返回十六进制文本字符串。首先,你必须使用 pack("H*", $hash_result) 将其转换为二进制字符串,然后才能对其进行 Base64 编码。

以下是连接并使用哈希密码添加用户的完整代码。你不必使用 {MD5},如果需要,可以选择其他哈希。其中一个哈希密码的输出将如下所示:{md5}bdwD04RS9xMDGVi1n/H36Q==

最后一些注意事项:如果使用盐值对密码进行哈希,则此技术将无法使用(但 Drupal 不会使用)。此技术肯定无法用于 Active Directory,因为 Active Directory 中的密码只能通过 SSL 连接设置,而且哈希方式可能不同。

---- 省略 ----

$ds = ldap_connect($serverAddress);
if ($ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // 否则 PHP 默认使用 ldap v2,你将收到语法错误!
$r = ldap_bind($ds, $managerDN, $managerPassword);
$ldaprecord['cn'] = $newuser_username;
$ldaprecord['givenName'] = $newuser_firstname;
$ldaprecord['sn'] = $newuser_surname;
// 将用户放入 objectClass inetOrgPerson 中,以便我们可以设置邮件和电话号码属性
$ldaprecord['objectclass'][0] = "person";
$ldaprecord['objectclass'][1] = "organizationalPerson";
$ldaprecord['objectclass'][2] = "inetOrgPerson";
$ldaprecord['mail'] = $newuser_email_address;
$ldaprecord['telephoneNumber'] = $newuser_phone_number;
// 现在是棘手的部分,对二进制哈希结果进行 Base64 编码
$ldaprecord['userPassword'] = '{MD5}' . base64_encode(pack('H*',$newuser_md5hashed_password));
// 如果你有明文密码,可以使用
// $ldaprecord['userPassword'] = '{MD5}' . base64_encode(pack('H*',md5($newuser_plaintext_password)));
$r = ldap_add($ds, $base_user_dn, $ldaprecord);
} else { die "无法连接到 LDAP 服务器 $serverAddress。"; }
6
Axel D. (FRANCE)
21 年前
如果你不知道如何在 AD Win2K 中添加用户,请尝试使用此脚本。
有关属性的更多信息,请在 Win2K 支持工具中打开 adsiedit 控制台。

$adduserAD["cn"][0] =
$adduserAD["instancetype"][0] =
$adduserAD["samaccountname"][0] =
$adduserAD["objectclass"][0] = "top";
$adduserAD["objectclass"][1] = "person";
$adduserAD["objectclass"][2] = "organizationalPerson";
$adduserAD["objectclass"][3] = "user";
$adduserAD["displayname"][0] =
$adduserAD["name"][0] =
$adduserAD["givenname"][0] =
$adduserAD["sn"][0] =
$adduserAD["company"][0] =
$adduserAD["department"][0] =
$adduserAD["title"][0] =
$adduserAD["description"][0] =
$adduserAD["mail"][0] =
$adduserAD["initials"][0] =
$adduserAD["samaccountname"][0] =
$adduserAD["userprincipalname"][0] =
$adduserAD["profilepath"][0] =
$adduserAD["manager"][0] = ***使用可分辨名称***

if (!($ldap = ldap_connect("localhost"))) {
die ("无法连接到 LDAP 服务器");
}
if (!($res = @ldap_bind($ldap, "[email protected]", $password))) {
die ("无法绑定到 LDAP 帐户");
}
if (!(ldap_add($ldap, "CN=New User,OU=OU Users,DC=pc,DC=com", $adduserAD))){
echo "创建帐户时出现问题
echo "请联系管理员!";
exit;
}
ldap_unbind($ldap);
5
theiderich AT laweekly dot com
19 年前
在为用户添加/编辑属性时,请记住“memberof”属性是一个特殊情况。MemberOf 属性不是用户模式的可访问属性。要将某人添加到组中,必须将用户添加到组中,而不是将组添加到用户中。你可以通过访问组属性“member”来实现此操作。

<?php

$group_name
= "CN=MyGroup,OU=Groups,DC=example,DC=com";
$group_info['member'] = $dn; // 用户的 DN 被添加到组的“member”数组中
ldap_mod_add($connect,$group_name,$group_info);

?>
2
ondrej dot duchon at t-systems dot cz
20 年前
jharnett at artschool dot com
对于 AD 中的活动用户,你必须将“useraccountcontrol”更改为 512,512 = 已启用,514 = 已禁用
4
phil at networkalliance dot com
16 年前
我创建了一个简单的函数,可以调用该函数以在 Active Directory 中创建全局分发组

<?php
function ldap_createGroup($object_name, $dn, $members, $ldap_conn)
{
$addgroup_ad['cn']="$object_name";
$addgroup_ad['objectClass'][0] = "top";
$addgroup_ad['objectClass'][1] ="group";
$addgroup_ad['groupType']="2";
$addgroup_ad['member']=$members;
$addgroup_ad["sAMAccountName"] =$object_name;

ldap_add($ldap_conn,$dn,$addgroup_ad);

if(
ldap_error($ldap_conn) == "Success")
return
true;
else
return
false;
}
?>

您可以使用以下代码调用此函数

<?php
$ldap_conn
= ldap_bind();
$object_name="Test Group";
$dn="CN=".$object_name.",OU=PathToAddGroupTo,OU=All Users,DC=YOURDOMAIN,DC=COM";
$members[] ="CN=User1,OU=PathToAddGroupTo,OU=All Users,DC=YOURDOMAIN,DC=COM";
$members[] ="CN=User2,OU=PathToAddGroupTo,OU=All Users,DC=YOURDOMAIN,DC=COM";

ldap_createGroup($object_name, $dn, $members, $ldap_conn);
?>

我创建的另一个函数是 ldap_bind(),它可以用来绑定到 LDAP 服务器

<?php
function ldap_bind()
{
$ldap_addr = '192.168.1.1'; // 将此更改为 LDAP 服务器的 IP 地址
$ldap_conn = ldap_connect($ldap_addr) or die("Couldn't connect!");
ldap_set_option($ldap_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
$ldap_rdn = "domain_name\\user_account";
$ldap_pass = "user_password";

// 验证用户对域控制器的身份
$flag_ldap = ldap_bind($ldap_conn,$ldap_rdn,$ldap_pass);
return
$ldap_conn;
}
?>
3
sergioshev
16 年前
当我使用布尔语法 (1.3.6.1.4.1.1466.115.121.1.7) 添加属性时遇到问题

$['boolean_attr']=true; // 给我一个警告,ldap_add(): Add: Invalid syntax

通过将值设置为以下值解决了这个问题

$['boolean_attr']='TRUE';

希望这可以帮助。
1
spam2004 at turniton dot dk
19 年前
在 Windows AD 中添加组..
$object_name="testgroup2";
$members[]="CN=THU,ou=Users,dc=addomain,dc=domain,dc=dk";
$members[]="CN=testgroup2,ou=Groups,dc=addomain,dc=domain,dc=dk";
$addgroup_ad['cn']="$object_name";
$addgroup_ad['objectClass'][0] = "top";
$addgroup_ad['objectClass'][1] ="group";
$addgroup_ad['descripton']=$object_description;
$addgroup_ad['member']=$members;
$addgroup_ad["sAMAccountName"] =$object_name;

// 注意参数 2 (dn) 可能会有所不同
$dn="cn=".$object_name.",ou=Groups,dc=addomain,dc=domain,dc=dk";
ldap_add($ldapc,$dn,$addgroup_ad);
1
John Van Atta
21 年前
针对 jharnett 关于从 ldap_add 中默认禁用的帐户的问题的回答,我们找到了一个解决方案。

属性 userAccountControl 包含一个值,其中包括帐户是否被禁用或启用。 我们的默认值为 546;当我们将它更改为 544 时,帐户被启用。 更改 userAccountControl 中的值似乎可以启用或禁用帐户。

以下代码对我们来说创建了一个启用帐户的新用户

$adduserAD["userAccountControl"] = "544";

我们只是将此元素添加到上面的示例数组中。
1
hp at syntomax dot com
19 年前
另一件有趣的事情:ldap_add() 不喜欢带有空成员的数组:所以
array (
[cn] = "name"
[key] = ""
[anotherkey] = "value"
)
将产生语法错误!

通过一个简单的代码段解决这个问题

foreach ($originalobject as $key => $value){
if ($value != ""){
$object[$key] = $value;
}
}

其中 $originalobject 是未经检查的数组,$object 是没有空成员的数组。
1
akohlsmith at mixdown dot org
24 年前
ldap_add() 仅在属性具有多个值时才支持 $entry["attribute"][x]="value"。 如果属性只有一个值,则*必须*将其输入为 $entry["attribute"]="value",否则 ldap_add() 会将属性的值设置为 "Array",而不是您在 $entry["attribute"][0] 中输入的值。

这里是我编写的一个小例程来自动执行此操作。 当您解析输入时,只需使用 multi_add()
<?php
function multi_add($attribute, $value)
{
global
$entry; // 您要添加的 LDAP 条目

if(isset($entry[$attribute]))
if(
is_array($entry[$attribute]))
$entry[$attribute][count($entry[$attribute])] = $value;
else
{
$tmp = $entry[$attribute];
unset(
$entry[$attribute]);
$entry[$attribute][0] = $tmp;
$entry[$attribute][1] = $value;
}
else
$entry[$attribute] = $value;
}
?>
multi_add() 检查属性是否已存在值。 如果没有,它会将其添加为 $entry[$attribute]=$value。 如果属性已经存在值,它会将属性转换为数组并正确添加多个值。

如何使用它
<?php
switch($form_data_name)
{
case
'phone': multi_add("telephoneNumber", $form_data_value); break;
case
'fax': multi_add("facsimileTelephoneNumber", $form_data_value); break;
case
'email': multi_add("mail", $form_data_value); break;
...
}
?>
在我设计的系统中,表单有下拉菜单,名称为 ctype1、ctype2、ctype3 等,值是 "fax、mail、phone..."。 实际的联系数据(电话号码、传真、电子邮件等)是 contact1、contact2、contact3 等。 用户从下拉菜单中选择联系类型(电话、电子邮件),然后输入数据(号码、地址等)。

我使用变量变量来填充条目并跳过空格。 这使得表单条目系统非常干净。 如果你对此感兴趣,请给我发邮件,因为我认为我超出了这里允许的笔记大小。 :-)
0
Baumkuchen.TH
5 年前
在 Active Directory 中创建组

<?php
$ds
= ldap_connect("IP-server/localhost");
$base_dn = "CN=Group name,OU=Organization Unit,DC=Domain-name,DC=com";// 组的识别名称

if ($ds) {
// 使用合适的识别名称绑定以提供更新访问权限
ldap_bind($ds, "CN=Administrator,OU=Organization Unit,DC=Domain-name,DC=com", "some-password");

// 在组中添加成员
$member_array = array();
$member_array[0] = "CN=Administrator,OU=Organization Unit,DC=Domain-name,DC=com";
$member_array[1] = "CN=User,OU=Organization Unit,DC=Domain-name,DC=com";

$entry["cn"] = "GroupTest";
$entry["samaccountname"] = "GroupTest";
$entry["objectClass"] = "Group";
$entry["description"] = "Group Test!!";
$entry["member"] = $member_array;
$entry["groupType"] = "2";// GroupType="2" 表示分发 / GroupType="1" 表示安全

ldap_add($ds,$base_dn,$entry);

ldap_close($ds);
} else {
echo
"无法连接到 LDAP 服务器";
}
?>
0
paul90brown at gmail dot com
11 年前
当我尝试添加 posixAccount 和 shadowAccount 作为对象类时,我一直收到“对象类违规”错误。事实证明,这些对象类有很多我未添加的必填字段。您可能需要导出一个可用的用户(如果您有 phpLDAPadmin)并查看其包含的字段,然后尝试在脚本中精确复制。如果您一开始将所有内容都设置为数组,也不会有什么坏处,您可以在以后修复这些字段。
0
chad dot smith at 50marketing dot com
18 年前
我借鉴了 turniton dot dk 网站上的 spam2004 示例,并对其进行了一些改进。也许我的设置有些不同,但无论如何,以下是我在 Microsoft Windows Server 2003 中添加组的方法。

<?php
// 使用 ldap_connect 连接
// 使用 ldap_bind 绑定
// 将 LDAP_OPT_PROTOCOL_VERSION 设置为 3
$member_array = array();
$member_array[0] = "cn=user1,cn=Users,dc=yourdomain,dc=com";
$member_array[1] = "cn=administrator,cn=Users,dc=yourdomain,dc=com";

$addgroup_ad["cn"] = "testgroup";
$addgroup_ad["samaccountname"] = "testgroup";
$addgroup_ad["objectClass"] = "Group";
$addgroup_ad["description"] = "Yep just a test.";
$addgroup_ad["member"] = $member_array;
$base_dn = "cn=testgroup,cn=Users,DC=yourdomain,DC=com";
ldap_add($ldap_conn,$base_dn,$addgroup_ad);
// 就这样
?>

保重,祝你好运!
Chad R. Smith
0
amcnabb
19 年前
小心类型。PHP 在字符串和数字之间自动切换,但 LDAP 不会,除非您指定类型,否则 PHP 将发送对 PHP 最方便的类型,而不是对 LDAP 最方便的类型。

如果您不小心将数字作为字符串发送,您将收到错误:“ldap_add(): Add: Invalid syntax in [filename] on line LINENUM”。

请看这个示例,它创建了一个数组,并将该数组发送给 LDAP 以创建 POSIX 组。请注意,$new_groupid 实际上是一个字符串,但必须使用 (int) 进行类型转换。

$new_ldap_group['cn'] = $groupname;
$new_ldap_group['objectclass'][0] = 'posixgroup';
$new_ldap_group['objectclass'][1] = 'top';
$new_ldap_group['gidnumber'] = (int) $new_groupid;
0
ondrej dot duchon at t-systems dot cz
20 年前
如果您需要使用国家字符(iso 8859-2、8 等),使用 ldap_set_option 是一种好方法。
找到错误所在真是太难了 ;-))). 希望这对某些人有所帮助。

ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
0
jharnett at artschool dot com
21 年前
由于某些奇怪的原因,使用 ldap_add() 添加新帐户时,帐户被设置为“inactive”。
据我所知,没有可修改的属性可以“重新启用”该用户。我想默认情况下,如果未设置特定标志,则使用默认值。如果有人找到了解决方法,请发布,我快要把仅存的几根头发都挠掉了。
0
del at babel dot com dot au
22 年前
如果您需要添加一个二进制编码的属性(例如:userCertificate),则需要在字段名称末尾添加“;binary”规范。

例如

$info["userCertificate;binary"] = $myBinaryCert;
$ldap_add ...

Del
0
titus dot stahl at experts4 dot com
22 年前
请注意,您不能使用 base64 编码,而必须使用 utf-8 编码来表示特殊字符。
-1
Willie
16 年前
回复
请注意,您不能使用 base64 编码,而必须使用 utf-8 编码来表示特殊字符。
--

我发现,如果我有特殊字符(或换行符),ldap_add 和 ldap_modify 会自动为您执行 base64 编码。例如

<?php
// 假设绑定已完成等
$entry['postalAddress'] = "123 East 456 West\nSuite A103";
ldap_modify($ds, $dn, $entry);
?>

该函数或服务器会将换行符转换为 base64(其他特殊字符也是如此)。

您可以使用命令行 ldapsearch 进行验证
ldapsearch -b "dc=example,dc=com" -x "(cn=Example Person)" postalAddress

您将看到结果为
dn: cn=Example Person,dc=example,dc=com
postalAddress:: MTIzIEVhc3QgNDU2IFdlc3QKU3VpdGUgQTEwMw==

您是否看到了 postal address 后的双冒号?这就是 LDAP 在这种情况下表示它为 base64 编码的方式。
-1
micattack+phpnet at gmail dot com
19 年前
当遇到令人讨厌的无效语法错误时,在 ldap 中打开调试很有帮助。查看 /var/log/ldap,您会看到类似以下内容

May 2 13:51:21 tux slapd[12985]: conn=4934 op=1 RESULT tag=105 err=21 text=phpgwtz: value #0 invalid per syntax
May 2 13:52:02 tux slapd[12697]: No objectClass for entry (uid=1, ou=adressen, dc=...
-1
Andrew (a.whyte at cqu.edu.au)
20 年前
关于帐户启用问题的回复,您可以使用 Microsoft 支持网站上的表格来帮助您处理这些属性。

您是对的,'2' 是帐户禁用标志,但还有其他标志,可以用于检测/设置密码强制过期等。

希望此 URL 对您有所帮助

http://support.microsoft.com/default.aspx?scid=kb;en-us;305144

干杯。
-4
Igor2i
10 年前
我决定专门为俄语用户添加此内容。
我的服务器是 Gentoo,支持以 UTF-8 编码的西里尔字母。
当我通过表单输入西里尔字母时,会显示语法错误。
解决方法
1) 需要将代码重新编码为无 BOM 的 UTF-8
2) 在代码开头插入以下行
<?php
header
('Content-Type: text/html; charset=utf-8');
?>
To Top