如何使用 LDIF 文件更改 OpenLDAP 系统
介绍
LDAP 是一种用于管理和与目录服务交互的协议。OpenLDAP 项目提供了符合 LDAP 的目录服务,可用于存储目录数据并提供目录数据的接口。
在本指南中,我们将讨论用于与 LDAP 目录通信的 LDIF 文件格式。我们将讨论可用于处理这些文件的工具,并根据指定的命令修改 LDAP 目录信息树。
先决条件
在开始本指南之前,您应该可以访问 OpenLDAP 服务器。您可以在此处了解如何设置 OpenLDAP 服务器。您应该熟悉使用 LDAP 目录服务时使用的基本术语。 本指南可用于进一步熟悉这些主题。
LDIF 格式
LDIF(LDAP 数据交换格式)是一种用于表示 LDAP 数据和命令的文本格式。使用 LDAP 系统时,您可能会使用 LDIF 格式来指定数据以及您希望对 LDAP DIT 进行的更改。
LDIF 旨在描述 LDAP 系统中的任何条目以及必须进行的任何修改。因此,其语法非常精确,乍一看似乎有些复杂。使用 LDIF,LDAP 更改可以简单地写入任意名称的文件中,然后使用可用的管理命令之一将其输入到 LDAP 系统中。
LDIF 使用基本的键值系统,每行一个语句。键位于行的左侧,后跟冒号 (:) 和空格。空格对于正确读取行非常重要。然后在右侧分配值。此格式适用于 LDAP 属性繁重的语法,但也可用于发出命令并提供有关如何解释内容的说明。
可以使用多行来提供属性的长值,方法是用一个空格开始多余的行。LDAP 将在处理条目时连接这些行。
向DIT添加条目
在 LDIF 文件中指定新条目有两种主要方法。最适合您需求的方法取决于您需要协调的其他更改类型。您选择的方法将决定您必须使用哪些工具和参数来将更改应用于 LDAP DIT(目录信息树)。
列出要添加到 DIT 的条目
定义要添加到 LDAP 的新条目的最基本方法是简单地列出所有条目,就像使用 LDAP 工具通常显示的那样。首先列出将创建条目的 DN(可分辨名称),然后列出指示符dn:
:
dn: ou=newgroup,dc=example,dc=com
在上面的行中,我们引用了一些键值对,以便为新条目构建 DN。设置属性值时,必须使用冒号和空格。引用属性/值时,应改用等号。
在向 DIT 添加条目的最简单的 LDIF 格式中,条目的其余部分只需使用此格式在 DN 定义下写出即可。必须设置必要的 objectClass 声明和属性才能构造有效条目。例如,要创建一个组织单位来包含我们组织员工的条目,我们可以使用以下命令:
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People
您可以在单个文件中添加多个条目。每个条目必须至少由一个完全空白的行分隔:
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People
dn: ou=othergroup,dc=example,dc=com
objectClass: organizationalUnit
ou: othergroup
如您所见,此 LDIF 格式几乎与您在查询 LDAP 树以查找包含此信息的条目时看到的格式完全相同。您几乎可以逐字逐句地写下您希望条目包含的内容。
使用“Changetype:Add”创建新条目
如果您在同一 LDIF 文件中进行其他修改,我们将要研究的第二种格式会很有效。OpenLDAP 提供了可以处理添加和修改的工具,因此如果我们在同一文件中修改其他条目,我们可以将新条目标记为添加,以便正确处理它们。
这看起来很像上面的方法,但我们changetype: add
直接在 DN 规范下面添加。例如,我们可以ou=People,dc=example,dc=com
使用 LDIF 将 John Smith 条目添加到已经包含结构的 DIT 中,如下所示:
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
description: John Smith from Accounting. John is the project
manager of the building project, so contact him with any que
stions.
cn: John Smith
sn: Smith
uid: jsmith1
这基本上就是我们迄今为止用来描述条目的格式,除了 DN 规范后面的附加行。在这里,我们告诉 LDAP 我们所做的更改是创建条目。由于我们使用了选项,因此该工具可以毫无问题地changetype
处理此条目,从而允许我们将其他类型的修改放在同一个 LDIF 文件中。该选项必须紧跟在 DN 规范之后。ldapmodify
changetype
上面需要注意的另一件事是属性的多行值的使用description
。由于后面的行以空格开头,因此它们将被连接起来并删除空格。我们示例中的第一个续行包含一个额外的空格,但这是句子本身的一部分,将单词“project”和“manager”分隔开。
与上一节一样,同一文件中的每个附加条目都用空行分隔。注释可以通过以字符开头的行来使用#
。注释必须位于其自己的行上。例如,如果我们想在同一个 LDIF 文件中添加 Sally,我们可以像这样分隔两个条目:
# Add John Smith to the organization
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
description: John Smith from Accounting. John is the project
manager of the building project, so contact him with any qu
estions.
cn: John Smith
sn: Smith
uid: jsmith1
# Add Sally Brown to the organization
dn: uid=sbrown20,ou=People,dc=example,dc=com
changetype: add
objectClass: inetOrgPerson
description: Sally Brown from engineering. Sally is responsibl
e for designing the blue prints and testing the structural int
egrity of the design.
cn: Sally Brown
sn: Brown
uid: sbrown20
处理条目添加
现在我们知道如何构建 LDIF 文件来添加新条目,我们需要使用 LDAP 工具实际处理这些文件以将它们添加到 DIT。您使用的工具和/或参数将取决于您上面选择的形式。
如果您使用的是简单条目格式(没有设置changetype
),则可以使用命令ldapadd
或ldapmodify
带有-a
标志的命令,该标志指定条目添加。您需要使用 SASL 方法对 LDAP 实例进行身份验证(这超出了本指南的范围),或者绑定到 DIT 中的管理帐户并提供所需的密码。
例如,如果我们将简单条目部分的条目存储在名为的文件中newgroups.ldif
,则处理该文件并添加新条目所需的命令将如下所示:
ldapadd -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f newgroups.ldif
您也可以使用ldapmodify -a
组合来获得相同的结果:
ldapmodify -a -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f newgroups.ldif
如果您使用第二种格式,即带有changetype
声明的格式,则需要使用ldapmodify
不带-a
标志的命令。由于此命令和格式适用于大多数其他修改,因此对于大多数更改来说,它可能更容易使用。如果我们将两个新用户添加存储在名为的文件中newusers.ldif
,我们可以通过键入以下内容将其添加到我们现有的 DIT 中:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f newusers.ldif
这样您就可以随意向 DIT 添加条目。您可以轻松地将许多条目存储在单个 LDIF 文件中,并使用单个命令填充 DIT。
从 DIT 中删除条目
我们在上一节中第一次看到了该changetype
选项。此选项提供了指定我们希望进行的高级修改类型的方法。对于条目删除,此选项的值为“delete”。
条目删除实际上是您可以执行的最直接的更改,因为唯一需要的信息是 DN。
例如,如果我们想ou=othergroup
从 DIT 中删除条目,我们的 LDIF 文件只需要包含以下内容:
dn: ou=othergroup,dc=example,dc=com
changetype: delete
要处理更改,您可以使用ldapmodify
上面使用的确切格式。如果我们使用删除请求调用文件rmothergroup.ldif
,我们将像这样应用它:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f rmothergroup.ldif
这将ou=othergroup
立即从系统中删除该条目。
修改条目的属性
修改条目的属性是一种非常常见的更改,通过在条目的 DN 后指定即可实现changetype: modify
。您可以对属性进行的修改类型大部分与您可以对条目本身进行的修改相同。因此,请求的属性更改类型的详细信息在之后使用附加指令指定。
向条目添加属性
例如,您可以使用add:
后面的命令添加属性changetype: modify
。这应该指定您想要添加的属性。然后,您可以像平常一样设置属性的值。因此,基本格式为:
dn: entry_to_add_attribute
changetype: modify
add: attribute_type
attribute_type: value_to_set
例如,要向我们的帐户添加一些电子邮件地址,我们可以创建一个如下所示的 LDIF 文件:
dn: uid=sbrown20,ou=People,dc=example,dc=com
changetype: modify
add: mail
mail: sbrown@example.com
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: modify
add: mail
mail: jsmith1@example.com
mail: johnsmith@example.com
从第二条条目可以看出,您可以同时指定多个添加项。该mail
属性允许有多个值,因此这是允许的。
您可以照常处理此问题ldapmodify
。如果更改在文件中sbrownaddmail.ldif
,您可以输入:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f sbrownaddmail.ldif
替换条目中属性的值
另一个常见的更改是修改属性的现有值。我们可以使用replace:
下面的选项来执行此操作changetype: modify
。
其操作方式与add:
命令几乎相同,但默认情况下,从条目中删除属性的每个现有实例,并将其替换为之后定义的值。例如,如果我们注意到上一个命令的电子邮件不正确,我们可以使用以下命令add:
进行修改:replace
dn: uid=sbrown20,ou=People,dc=example,dc=com
changetype: modify
replace: mail
mail: sbrown2@example.com
请记住,这将替换条目中的每个实例。这对于可以为每个条目定义多次的多值属性(如)非常重要。如果您只想替换单个出现的属性,则应结合使用属性选项(如下所述)和属性选项(如上所述)。mail
mail
delete:
add:
如果这个更改存储在名为的文件中sbrownchangemail.ldif
,我们可以通过输入以下内容替换Sally的电子邮件:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f sbrownchangemail.ldif
从条目中删除属性
如果您希望从条目中删除属性,可以使用该delete:
命令。您将指定要删除的属性作为选项的值。如果您希望删除属性的特定实例,您可以在下一行指定特定的键值属性出现。否则,条目中该属性的每个出现都将被删除。
例如,这将删除 John Smith 的条目中的每个描述属性:
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: modify
delete: description
但是,这只会删除指定的电子邮件:
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: modify
delete: mail
mail: jsmith1@example.com
由于我们之前向约翰提供了两个电子邮件地址,因此此请求应保持不变的另一个电子邮件地址。
如果这些更改位于名为jsmithrmdesc.ldif
和 的文件中jsmithrmextramail.ldif
,我们可以通过键入以下内容来应用它们:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f jsmithrmdesc.ldif
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f jsmithrmextramail.ldif
指定多个属性更改
现在是讨论同时指定多个属性更改的好时机。对于 LDIF 文件中的单个条目,您可以通过用仅包含字符的行分隔它们来指定多个属性更改-
。在分隔符之后,必须指定属性更改类型,并且必须提供所需的属性。
例如,我们可以删除 John 的剩余电子邮件属性,将他的名字更改为“Johnny Smith”,并通过创建包含以下内容的文件来添加他的位置:
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: modify
delete: mail
-
replace: cn
cn: Johnny Smith
-
add: l
l: New York
要在一个命令中应用所有这些更改,我们将使用ldapmodify
一直使用的相同格式:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f multichange.ldif
重命名和移动条目
该changetype: modrdn
选项可以重命名或移动现有条目。指定dn:
要定位的对象后,设置该changetype: modrdn
选项。
重命名条目
假设我们最初将 Sally 的用户名输入系统时输入错误。由于该用户名用于条目的 DN,因此不能简单地用和changetype: modify
选项替换它replace:
,因为条目的 RDN 无效。如果她的真实用户名是sbrown200
,我们可以使用如下所示的 LDIF 文件更改条目的 DN,并在此过程中创建任何必要的属性:
dn: uid=sbrown20,ou=People,dc=example,dc=com
changetype: modrdn
newrdn: uid=sbrown200
deleteoldrdn: 0
我们可以使用以下命令应用此更改:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f fixsallydn.ldif
这将使完整的条目看起来像这样:
dn: uid=sbrown200,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
description: Sally Brown from engineering. Sally is responsibl
e for designing the blue prints and testing the structural int
egrity of the design.
cn: Sally Brown
sn: Brown
uid: sbrown20
uid: sbrown200
mail: sbrown2@example.com
如您所见,我们的 DN 已调整为使用新的属性/值对。属性已添加到条目中以实现此目的。
您可能已经注意到上面示例中的两件事。首先,我们将一个名为的选项设置deleteoldrdn
为“0”。其次,结果条目同时包含uid: sbrown20
和uid: sbrown200
。
deleteoldrdn
更改条目的 DN 时必须设置此选项。设置deleteoldrdn
为“0”会导致 LDAP 将 DN 中使用的旧属性与条目中的新属性一起保留。有时这是您想要的,但通常您会希望在 DN 更改后从条目中完全删除旧属性。您可以通过将其设置deleteoldrdn
为“1”来实现这一点。
假设我们又犯了一个错误,Sally 的实际用户名是sbrown2
。我们可以将其设置deleteoldrdn
为“1”,以sbrown200
从重命名后的条目中删除当前在 DN 中使用的实例。我们将继续添加一个额外的changetype: modify
和delete:
对,以摆脱另一个流浪用户名 ,sbrown20
因为我们在第一次重命名时保留了它:
dn: uid=sbrown200,ou=People,dc=example,dc=com
changetype: modrdn
newrdn: uid=sbrown2
deleteoldrdn: 1
dn: uid=sbrown2,ou=People,dc=example,dc=com
changetype: modify
delete: uid
uid: sbrown20
像这样应用文件:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f fix2sallydn.ldif
此组合不会随着更改而添加新的用户名(sbrown200
将被删除),并且第二次条目修改将删除用户名的原始值(sbrown20
)。
移动条目
如果需要将条目移动到新位置,则changetype: modrdn
可以使用newsuperior:
选项进行附加设置。使用此选项时,您可以在 DIT 上指定要将条目移动到的新位置。这会在更改期间将条目置于指定的父 DN 下。
例如,如果我们想将 Sally 移到ou=superusers
条目下,我们可以添加此条目,然后通过键入以下内容将她移动到其中:
dn: ou=superusers,dc=example,dc=com
changetype: add
objectClass: organizationalUnit
ou: superusers
dn: uid=sbrown2,ou=People,dc=example,dc=com
changetype: modrdn
newrdn: uid=sbrown2
deleteoldrdn: 0
newsuperior: ou=superusers,dc=example,dc=com
假设它存储在名为的文件中mksuperuser.ldif
,我们可以像这样应用更改:
ldapmodify -x -D "cn=admin,dc=example,dc=com" -w password -H ldap:// -f mksuperuser.ldif
这会导致移动而不是复制。
In this case, we did not wish to actually change the RDN of the entry, so we set the newrdn:
value to the same value that it currently has. We could easily rename during the move too though if we so desired. In this case, the newsuperior:
setting is the only line of the second change that actually impacts the state of the entry.
An Aside: Adding Binary Data to an Entry
This section is separate from the information above because it could fit within the sections on creating an entry or with defining additional attributes.
LDAP has the ability to store binary data for certain attributes. For instance, the inetOrgPerson
class allows an attribute called jpegPhoto
, which can be used to store a person’s photograph or user icon. Another attribute of this objectClass that can use binary data is the audio
attribute.
To add this type of data to an LDAP entry, you must use a special format. When specifying the attribute, immediately following the colon, use a less-than character (<) and a space. Afterwards, include the path to the file in question.
For instance, if you have a file called john.jpg
in the /tmp
directory, you can add the file to John’s entry with an LDIF file that looks like this:
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: modify
add: jpegPhoto
jpegPhoto:< file:///tmp/john.jpg
Pay close attention to the placement of the colon, less than character, and space. If your file is located on disk, the file://
prefix can be used. The path will add an additional slash to indicate the root directory if you are using an absolute path.
This would work the same way with an audio file:
dn: uid=jsmith1,ou=People,dc=example,dc=com
changetype: modify
add: audio
audio:< file:///tmp/hellojohn.mp3
Once you have processed the LDIF file, the actual file will be encoded within your LDAP directory service. This is important to keep in mind, because adding significant number of files like this will have an impact on the size and performance of your service.
When you need to retrieve the encoded data using the ldapsearch
tool, you will need to add the -t
flag, which will allow the file to be written to the /tmp
directory. The generated filename will be indicated in the results.
For instance, we could use this command to write out the binary data to a temporary file:
ldapsearch -LLL -x -H ldap:// -t -b "dc=example,dc=com" "uid=jsmith1"
The search result will look like this:
dn: uid=jsmith1,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
sn: Smith
uid: jsmith1
cn: Johnny Smith
l: New York
audio:< file:///tmp/ldapsearch-audio-n5GRF6
If we go to the /tmp
directory, we can find the file. It can be renamed as needed and should be in the exact state that it was in before entering it into the directory.
Be careful when doing this operation repeatedly, as a new file is written out each time the search is performed. You could easily fill a disk without realizing if you do not pay attention.
Conclusion
现在,您应该已经相当了解如何使用 LDIF 格式的文件和一些工具来操作 LDAP 目录信息树中的条目。虽然某些 LDAP 客户端可能使 LDIF 文件对于日常操作来说不再必要,但 LDIF 文件可能是对 DIT 条目执行批处理操作的最佳方式。在设置初始目录服务时以及在修复可能阻止客户端正确访问数据的问题时,了解如何使用这些方法修改条目以用于管理目的也很重要。