很多网友可能跟我一样,要学LDAP,但是对此还是很陌生!因此我整理一下我的学习经验,与大家共享,学习它之前,肯定要知道它是什么?并且知道功能是什么?特别是LDAP,你还要了解一下结构是什么?是怎么排列的!
OK,那我们先了解一下什么是LDAP吧,这里有两份比较权威的资料,分中英文版!在此对作者的OPEN精神表示感谢!
附:土哥的E文水平不是很好,看英文版的很辛苦!这里有两篇中英文对照的,对学LDAP和E文都有帮助,呵,真所谓的一石二鸟,呵其实也是一箭又雕了!呵...
原文地址:http://ldapman.org/articles/intro_to_ldap.html
An Introduction to LDAP
If you work in the computing industry, the chances are good that you've heard of LDAP by now. Wondering what all the excitement is about? Want to know a little more about the underlying technology? You've come to the right place. This introduction - the first in a series of articles describing how to design, implement, and integrate an LDAP environment at your company - will familiarize you with the concepts behind LDAP while leaving the really hardcore details for later. Here, we'll touch on the following topics:
- What is LDAP, anyway?
- When should you use LDAP to store your data?
- The structure of an LDAP directory tree
- Individual LDAP records
- Customizing your directory's object classes
- An example of an individual LDAP entry
- LDAP replication
- Security and access control
To start with, what's happening with LDAP today is exciting. A company-wide LDAP implementation can enable almost any application, running on almost any computer platform, to obtain information from your LDAP directory. And that directory can be used to store a broad range of data: email address and mail routing information, HR data, public security keys, contact lists, and much more. By making an LDAP directory a focal point in your systems integration, you're providing one-stop shopping whenever people go looking for information within your company - even if the primary source of the data lives elsewhere.
But wait, you say. You're already using an Oracle, Sybase, Informix, or Microsoft SQL database to store much of that same data. How is LDAP different? What makes it better? Read on.
The Lightweight Directory Access Protocol, better known as LDAP, is based on the X.500 standard, but significantly simpler and more readily adapted to meet custom needs. Unlike X.500, LDAP supports TCP/IP, which is necessary for Internet access. The core LDAP specifications are all defined in RFCs -- a complete list of LDAP-related RFCs may be found at the LDAPman RFC page.
Using "LDAP" in a sentence
In everyday conversation, you'll hear well-intentioned people say things like, "Should we be storing that in LDAP?" or "Just get that data from the LDAP database," or "How do we go about tying LDAP into an RDB?" Strictly speaking, though, LDAP isn't a database at all, but a protocol used to access information stored in an information directory (also known as an LDAP directory). A more precise formulation might look something like this: "Using LDAP, data will be retrieved from (or stored in) the correct location within our information directory." But you won't find me correcting anyone on this point: either way, you get the idea across, and that's what counts.
Is an LDAP information directory a database?
Just as a Database Management System (DBMS) from Sybase, Oracle, Informix, or Microsoft is used to process queries and updates to a relational database, an LDAP server is used to process queries and updates to an LDAP information directory. In other words, an LDAP information directory is a type of database, but it's not a relational database. And unlike databases that are designed for processing hundreds or thousands of changes per minute - such as the Online Transaction Processing (OLTP) systems often used in e-commerce - LDAP directories are heavily optimized for read performance.
The advantages of LDAP directories
Now that we've straightened that out, what are the advantages of LDAP directories? The current popularity of LDAP is the culmination of a number of factors. I'll give you a few basic reasons, provided you keep in mind that it's just part of the story.
Perhaps the biggest plus for LDAP is that your company can access the LDAP directory from almost any computing platform, from any one of the increasing number of readily available, LDAP-aware applications. It's also easy to customize your company's internal applications to add LDAP support.
The LDAP protocol is both cross-platform and standards-based, so applications needn't worry about the type of server hosting the directory. In fact, LDAP is finding much wider industry acceptance because of its status as an Internet standard. Vendors are more willing to write LDAP integration into their products because they don't have to worry about what's at the other end. Your LDAP server could be any one of a number of open-source or commercial LDAP directory servers (or perhaps even a DBMS server with an LDAP interface), since interacting with any true LDAP server involves the same protocol, client connection package, and query commands. By contrast, vendors looking to integrate directly with a DBMS usually must tailor their product to work with each database server vendor individually.
Unlike many relational databases, you do not have to pay for either client connection software or for licensing.
Most LDAP servers are simple to install, easily maintained, and easily optimized.
LDAP servers can replicate either some or all of their data via push or pull methods, allowing you to push data to remote offices, to increase security, and so on. The replication technology is built-in and easy to configure. By contrast, many of the big DBMS vendors charge extra for this feature, and it's far more difficult to manage.
LDAP allows you to securely delegate read and modification authority based on your specific needs using ACIs (collectively, an ACL, or Access Control List). For example, your facilities group might be given access to change an employee's location, cube, or office number, but not be allowed to modify entries for any other fields. ACIs can control access depending on who is asking for the data, what data is being asked for, where the data is stored, and other aspects of the record being modified. This is all done through the LDAP directory directly, so you needn't worry about making security checks at the user application level.
LDAP is particularly useful for storing information that you wish to read from many locations, but update infrequently. For example, your company could store all of the following very efficiently in an LDAP directory:
- The company employee phone book and organizational chart
- External customer contact information
- Infrastructure services information, including NIS maps, email aliases, and so on
- Configuration information for distributed software packages
- Public certificates and security keys
When should you use LDAP to store your data?
Most LDAP servers are heavily optimized for read-intensive operations. Because of this, one can typically see an order of magnitude difference when reading data from an LDAP directory versus obtaining the same data from a relational database server optimized for OLTP. Because of this optimization, however, most LDAP directories are not well suited for storing data where changes are frequent. For instance, an LDAP directory server is great for storing your company's internal telephone directory, but don't even think of using it as a database back end for your high-volume e-commerce site.
If the answer to each of the following questions is Yes, then storing your data in LDAP is a good idea.
- Would you like your data to be available cross-platform?
- Do you need to access this data from a number of computers or applications?
- Do the individual records you're storing change a few times a day or less, on average?
- Does it make sense to store this type of data in a flat database instead of a relational database? That is, could you effectively store all the data for a given item in a single record?
This final question often gives people pause, because it's very common to access a flat record to obtain data that's relational in nature. For example, a record for a company employee might include the login name of that employee's manager. It's fine to use LDAP to store this kind of information. Rule of thumb: If you can imagine storing your data in a large electronic Rolodex, you can store it easily in an LDAP directory.
The structure of an LDAP directory tree
LDAP directory servers store their data hierarchically. If you've seen the top-down representations of DNS trees or UNIX file directories, an LDAP directory structure will be familiar ground. As with DNS host names, an LDAP directory record's Distinguished Name (DN for short) is read from the individual entry, backwards through the tree, up to the top level. More on this point later.
Why break things up into a hierarchy? There are a number of reasons. Here are a few possible scenarios:
- You may wish to push all your US-based customer contact information to an LDAP server in the Seattle office (which is devoted to sales), whereas you probably don't need to push the company's asset management information there.
- You may wish to grant permissions to a group of individuals based on the directory structure. In the example listed below, the company's asset management team might need full access to the asset-mgmt section, but not to other areas.
- Combined with replication, you can tailor the layout of your directory structure to minimize WAN bandwidth utilization. Your sales office in Seattle might need up-to-the minute updates for US sales contacts, but only hourly updates for European sales information.
Getting to the root of the matter: Your base DN and you
The top level of the LDAP directory tree is the base, referred to as the "base DN." A base DN usually takes one of the three forms listed here. Let's assume I work at a US electronic commerce company called FooBar, Inc., which is on the Internet at foobar.com.
o="FooBar, Inc.", c=US
(base DN in X.500 format)
In this example, o=FooBar, Inc. refers to the organization, which in this context should be treated as synonymous with the company name. c=US indicates that the company headquarters is in the US. Once upon a time, this was the preferred method of specifying your base DN. Times and fashions change, though; these days, most companies are (or plan to be) on the Internet. And what with Internet globalization, using a country code in the base DN probably made things more confusing in the end. In time, the X.500 format evolved into the other formats listed below.
o=foobar.com
(base DN derived from the company's Internet presence)
This format is fairly straightforward, using the company's Internet domain name as the base. Once you get past the o= portion (which stands for organization=), everyone at your company should know where the rest came from. This was, until recently, probably the most common of the currently used formats.
dc=foobar, dc=com
(base DN derived from the company's DNS domain components)
As with the previous format, this uses the DNS domain name as its basis. But where the other format leaves the domain name intact (and thus human-readable), this format is split into domain components: foobar.com becomes dc=foobar, dc=com. In theory, this could be slightly more versatile, though it's a little harder for end users to remember. By way of illustration, consider foobar.com. When foobar.com merges with gizmo.com, you simply start thinking of "dc=com" as the base DN. Place the new records into your existing directory under dc=gizmo, dc=com, and you're ready to go. (Of course, this approach doesn't help if foobar.com merges with wocket.edu.) This is the format I'd recommend for any new installations. Oh, and if you're planning to use Active Directory, Microsoft has already decided for you that this is the format you wanted.
Time to branch out: How to organize your data in your directory tree
In a UNIX file system, the top level is the root. Beneath the root you have numerous files and directories. As mentioned above, LDAP directories are set up in much the same manner.
Underneath your directory's base, you'll want to create containers that logically separate your data. For historical (X.500) reasons, most LDAP directories set these logical separations up as OU entries. OU stands for "Organizational Unit," which in X.500 was used to indicate the functional organization within a company: sales, finance, et cetera. Current LDAP implementations have kept the ou= naming convention, but break things apart by broad categories like ou=people, ou=groups, ou=devices, and so on. Lower level OUs are sometimes used to break categories down further. For example, an LDAP directory tree (not including individual entries) might look like this:
dc=foobar, dc=com ou=customers ou=asia ou=europe ou=usa ou=employees ou=rooms ou=groups ou=assets-mgmt ou=nisgroups ou=recipes
What's in a name? The DN of an LDAP entry
All entries stored in an LDAP directory have a unique "Distinguished Name," or DN. The DN for each LDAP entry is composed of two parts: the Relative Distinguished Name (RDN) and the location within the LDAP directory where the record resides.
The RDN is the portion of your DN that is not related to the directory tree structure. Most items that you'll store in an LDAP directory will have a name, and the name is frequently stored in the cn (Common Name) attribute. Since nearly everything has a name, most objects you'll store in LDAP will use their cn value as the basis for their RDN. If I'm storing a record for my favorite oatmeal recipe, I'll be using cn=Oatmeal Deluxe as the RDN of my entry.
- My directory's base DN is dc=foobar,dc=com
- I'm storing all the LDAP records for my recipes in ou=recipes
- The RDN of my LDAP record is cn=Oatmeal Deluxe
Given all this, what's the full DN of the LDAP record for this oatmeal recipe? Remember, it reads backwards - just like a host name in DNS.
cn=Oatmeal Deluxe,ou=recipes,dc=foobar,dc=com
People are always more trouble than inanimate objects
Now it's time to tackle the DN of a company employee. For user accounts, you'll typically see a DN based either on the cn or on the uid (User ID). For example, the DN for FooBar's employee Fran Smith (login name: fsmith) might look like either of these two formats:
uid=fsmith,ou=employees,dc=foobar,dc=com
(login-based)
LDAP (and X.500) use uid to mean "User ID", not to be confused with the UNIX uid number. Most companies try to give everyone a unique login name, so this approach makes good sense for storing information about employees. You don't have to worry about what you'll do when you hire the next Fran Smith, and if Fran changes her name (marriage? divorce? religious experience?), you won't have to change the DN of the LDAP entry.
cn=Fran Smith,ou=employees,dc=foobar,dc=com
(name-based)
Here we see the Common Name (CN) entry used. In the case of an LDAP record for a person, think of the common name as their full name. One can easily see the downside to this approach: if the name changes, the LDAP record has to "move" from one DN to another. As indicated above, you want to avoid changing the DN of an entry whenever possible.
Customizing your directory's object classes
You can use LDAP to store data on almost any type of object, as long as that object can be described in terms of various attributes. Here are a few examples of information you might store:
- Employees: What's the employee's full name, login name, password, employee number, manager's login, mail server?
- Asset tracking: What's the computer name, IP address, asset tag, make and model information, physical location?
- Customer contact lists: What's the customer's company name? The primary contact's phone, fax, and email information?
- Meeting room information: What's the room name, location, seating capacity, telephone number? Is there wheelchair access? Is there an overhead projector?
- Recipe information: Give the name of the dish, the list of ingredients, the type of cuisine, and instructions for preparing it.
Because your LDAP directory can be customized to store any type of text or binary data, what you store is really up to you. LDAP directories use the concept of object classes to define which attributes are allowed for objects of any given type. In almost every LDAP implementation, you'll want to extend the basic functionality of your LDAP directory to meet your specific needs, either by creating new object classes or by extending existing ones.
LDAP directories store all information for a given record's entries as a series of attribute pairs, each one consisting of an attribute type and an attribute value. (This is completely different from the way relational database servers store data, in columns and rows.) Consider this portion of my recipe record, as stored in an LDAP directory:
dn: cn=Oatmeal Deluxe, ou=recipes, dc=foobar, dc=com cn: Instant Oatmeal Deluxe recipeCuisine: breakfast recipeIngredient: 1 packet instant oatmeal recipeIngredient: 1 cup water recipeIngredient: 1 pinch salt recipeIngredient: 1 tsp brown sugar recipeIngredient: 1/4 apple, any type
Note that in this case, each ingredient is listed as a value of attribute type recipeIngredient. LDAP directories are designed to store multiple values of a single type in this fashion, rather than storing the entire list in a single database field with some sort of delimiter to distinguish the individual values.
Because the data is stored in this way, the shape of the database can be completely fluid - you don't need to recreate a database table (and all its indexes) to start tracking a new piece of data. Even more important, LDAP directories use no memory or storage to handle "empty" fields - in fact, having unused optional fields costs you nothing at all.
An example of an individual LDAP entry
Let's look at an example. We'll use the LDAP record of Fran Smith, our friendly employee from Foobar, Inc. The format of this entry is LDIF, the format used when exporting and importing LDAP directory entries.
dn: uid=fsmith, ou=employees, dc=foobar, dc=com objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson objectclass: foobarPerson uid: fsmith givenname: Fran sn: Smith cn: Fran Smith cn: Frances Smith telephonenumber: 510-555-1234 roomnumber: 122G o: Foobar, Inc. mailRoutingAddress: fsmith@foobar.com mailhost: mail.foobar.com userpassword: {crypt}3x1231v76T89N uidnumber: 1234 gidnumber: 1200 homedirectory: /home/fsmith loginshell: /usr/local/bin/bash
To start with, attribute values are stored with case intact, but searches against them are case-insensitive by default. Certain attributes (like password) are case-sensitive when searching.
Let's break this entry down and look at it piece by piece.
dn: uid=fsmith, ou=employees, dc=foobar, dc=com
This is the full DN of Fran's LDAP entry, including the whole path to the entry in the directory tree. LDAP (and X.500) use uid to mean "User ID," not to be confused with the UNIX uid number.
objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson objectclass: foobarPerson
One can assign as many object classes as are applicable to any given type of object. The person object class requires that the cn (common name) and sn (surname) fields have values. Object Class person also allows other optional fields, including givenname, telephonenumber, and so on. The object class organizationalPerson adds more options to the values from person, and inetOrgPerson adds still more options to that (including email information). Finally, foobarPerson is Foobar's customized object class that adds all the custom attributes they wish to track at their company.
uid: fsmith givenname: Fran sn: Smith cn: Fran Smith cn: Frances Smith telephonenumber: 510-555-1234 roomnumber: 122G o: Foobar, Inc.
As mentioned before, uid stands for User ID. Just translate it in your head to "login" whenever you see it.
Note that there are multiple entries for the CN. As mentioned above, LDAP allows some attributes to have multiple values, with the number of values being arbitrary. When would you want this? Let's say you're searching the company LDAP directory for Fran's phone number. While you might know her as Fran (having heard her spill her guts over lunchtime margaritas on more than one occasion), the people in HR may refer to her (somewhat more formally) as Frances. Because both versions of her name are stored, either search will successfully look up Fran's telephone number, email, cube number, and so on.
mailRoutingAddress: fsmith@foobar.com mailhost: mail.foobar.com
Like most companies on the Internet, Foobar uses Sendmail for internal mail delivery and routing. Foobar stores all users' mail routing information in LDAP, which is fully supported by recent versions of Sendmail.
userpassword: {crypt}3x1231v76T89N uidnumber: 1234 gidnumber: 1200 gecos: Frances Smith homedirectory: /home/fsmith loginshell: /usr/local/bin/bash
Note that Foobar's systems administrators store all the NIS password map information in LDAP as well. At Foobar, the foobarPerson object class adds this capability. Note that the user password is stored in UNIX crypt format. The UNIX uid is stored here as uidnumber. Mind you, there's a whole RFC on storing NIS information in LDAP. I'll talk about NIS integration in a future article.
LDAP servers can be set to replicate some or all of their data, on a push or a pull basis, using simple authentication or certificate-based authentication.
For example, Foobar has a "public" LDAP server running on ldap.foobar.com, port 389. This server is used by Netscape Communicator's pinpoint email addressing feature, the "ph" command from UNIX, and other locations where a user would want to query for the phone number of an employee or customer contact. The company's master LDAP server is running on the same system, but on port 1389 instead.
You wouldn't necessarily want employees searching the directory to query against asset management or recipe data, nor would it be desirable to see IT accounts (like "root") showing up on the company directory. To accomodate these unpleasant realities, Foobar replicates selected directory subtrees from its master LDAP server to its "public" server. The replication excludes subtrees containing data they wish to hide. To keep things current at all times, the master directory server is set to do immediate push-based synchronization. Note that this approach is designed for convenience, not security: the idea is to allow power users to simply query the other LDAP port if they want to search all available data.
Let's say Foobar is managing its customer contact information via LDAP, over a low bandwidth connection between Oakland and Europe. They might set up replication from ldap.foobar.com:1389 to munich-ldap.foobar.com:389 as follows:
periodic pull: ou=asia,ou=customers,o=sendmail.com periodic pull: ou=us,ou=customers,o=sendmail.com immediate push: ou=europe,ou=customers,o=sendmail.com
The pull connections would keep things in sync every 15 minutes, which would probably be just fine in this scenario. The push connection would guarantee that any change made to the European contact information would be pushed out to Munich immediately.
Given this replication scheme, where would users connect to access their data? Users in Munich could simply connect to their local server. If they were making changes to the data, the local LDAP server would refer those changes to the master LDAP server, which would then push all the changes back to the local LDAP server to keep it in sync. This is of tremendous benefit to the local user: all their LDAP queries (mostly reads) are against their local server, which is substantially faster. When it's time to make a change to their information, end users needn't worry about reconfiguring their client software, because the LDAP directory servers handle the data exchange for them.
LDAP provides for a complex level of access control instances, or ACIs. Because the access can be controlled on the server side, it's much more secure than security methods that work by securing data through client software.
With LDAP ACIs, you can do things like:
- Grant users the ability to change their home phone number and home address, while restricting them to read-only access for other data types (such as job title or manager's login).
- Grant anyone in the group "HR-admins" the ability to modify any user's information for the following fields: manager, job title, employee ID number, department name, and department number. There would be no write permission to other fields.
- Deny read access to anyone attempting to query LDAP for a user's password, while still allowing a user to change his or her own password.
- Grant managers read-only permission for the home phone numbers of their direct reports, while denying this privilege to anyone else.
- Grant anyone in the group "host-admins" to create, delete, and edit all aspects of host information stored in LDAP.
- Via a Web page, allow people in "foobar-sales" to selectively grant or deny themselves read access to subsets of the customer contact database. This would, in turn, allow these individuals to download the customer contact information to their local laptops or to a PDA. (This will be most useful if your sales force automation tool is LDAP-aware.)
- Via a Web page, allow any group owner to add or remove any entries from groups they own. For example, this would allow sales managers to grant or remove access for salespeople to modify Web pages. This would allow owners of mail aliases to add and remove users without having to contact IT. Mailing lists designated as "public" could allow users to add or remove themselves (but only themselves) to or from those mail aliases. Restrictions can also be based on IP address or hostname. For example, fields can be made readable only if the user's IP address begins with 192.168.200.*, or if the user's reverse DNS hostname maps to *.foobar.com.
This will give you an idea what's possible using access control with LDAP directories, but be aware that a correct implementation requires much more information than is given here. I'll discuss access control in greater detail in a future article.
That's it for now. I hope you've found this article useful. If you have comments or questions, send email to donnelly@ldapman.org.
28 april 2000
介绍LDAP
原文:http://ldapman.org/articles/intro_to_ldap.html
原文作者:Michael Donnelly
翻译:Brimmer
如果你在计算机行业工作,那么对LDAP可能早有耳闻了。想深入地了解LDAP吗?那么可以好好地读一下这篇文章。这篇介绍性的文章是一系列介绍如何在企业中设计、实现和集成LDAP环境的文章的头一篇。主要是先让你熟悉一下LDAP的基本概念,那些比较困难的细节问题将放到以后讨论。在这篇文章中我们将要介绍:
现在LDAP技术不仅发展得很快而且也是激动人心的。在企业范围内实现LDAP可以让运行在几乎所有计算机平台上的所有的应用程序从LDAP目录中获取信息。LDAP目录中可以存储各种类型的数据:电子邮件地址、邮件路由信息、人力资源数据、公用密匙、联系人列表,等等。通过把LDAP目录作为系统集成中的一个重要环节,可以简化员工在企业内部查询信息的步骤,甚至连主要的数据源都可以放在任何地方。如果Oracle、Sybase、Informix或Microsoft SQL数据库中已经存储了类似的数据,那么LDAP和这些数据库到底有什么不同呢?是什么让它更具优势?请继续读下去吧!
什么是LDAP?
LDAP的英文全称是Lightweight Directory Access Protocol,一般都简称为LDAP。它是基于X.500标准的,但是简单多了并且可以根据需要定制。与X.500不同,LDAP支持TCP/IP,这对访问Internet是必须的。LDAP的核心规范在RFC中都有定义,所有与LDAP相关的RFC都可以在LDAPman RFC网页中找到。
怎么使用LDAP这个术语呢?
在日常交谈中,你可能会听到有些人这么说:“我们要把那些东西存在LDAP中吗?”,或者“从LDAP数据库中取出那些数据!”,又或者“我们怎么把LDAP和关系型数据库集成在一起?”。严格地说,LDAP根本不是数据库而是用来访问存储在信息目录(也就是LDAP目录)中的信息的协议。更为确切和正式的说法应该是象这样的:“通过使用LDAP,可以在信息目录的正确位置读取(或存储)数据”。但是,也没有必要吹毛求疵,尽管表达得不够准确,我们也都知道对方在说什么。
LDAP目录是数据库吗?
就象Sybase、Oracle、Informix或Microsoft的数据库管理系统(DBMS)是用于处理查询和更新关系型数据库那样,LDAP服务器也是用来处理查询和更新LDAP目录的。换句话来说LDAP目录也是一种类型的数据库,但是不是关系型数据库。不象被设计成每分钟需要处理成百上千条数据变化的数据库,例如:在电子商务中经常用到的在线交易处理(OLTP)系统,LDAP主要是优化数据读取的性能。
LDAP目录的优势
现在该说说LDAP目录到底有些什么优势了。现在LDAP的流行是很多因数共同作用的结果。我在这里说的不过是一些基本的原因,请你注意一下这不过是一小部分原因。
可能LDAP最大的优势是:可以在任何计算机平台上,用很容易获得的而且数目不断增加的LDAP的客户端程序访问LDAP目录。而且也很容易定制应用程序为它加上LDAP的支持。
LDAP协议是跨平台的和标准的协议,因此应用程序就不用为LDAP目录放在什么样的服务器上操心了。实际上,LDAP得到了业界的广泛认可,因为它是Internet的标准。产商都很愿意在产品中加入对LDAP的支持,因为他们根本不用考虑另一端(客户端或服务端)是怎么样的。LDAP服务器可以是任何一个开发源代码或商用的LDAP目录服务器(或者还可能是具有LDAP界面的关系型数据库),因为可以用同样的协议、客户端连接软件包和查询命令与LDAP服务器进行交互。与LDAP不同的是,如果软件产商想在软件产品中集成对DBMS的支持,那么通常都要对每一个数据库服务器单独定制。
不象很多商用的关系型数据库,你不必为LDAP的每一个客户端连接或许可协议付费。
大多数的LDAP服务器安装起来很简单,也容易维护和优化。
LDAP服务器可以用“推”或“拉”的方法复制部分或全部数据,例如:可以把数据“推”到远程的办公室,以增加数据的安全性。复制技术是内置在LDAP服务器中的而且很容易配置。如果要在DBMS中使用相同的复制功能,数据库产商就会要你支付额外的费用,而且也很难管理。
LDAP允许你根据需要使用ACI(一般都称为ACL或者访问控制列表)控制对数据读和写的权限。例如,设备管理员可以有权改变员工的工作地点和办公室号码,但是不允许改变记录中其它的域。ACI可以根据谁访问数据、访问什么数据、数据存在什么地方以及其它对数据进行访问控制。因为这些都是由LDAP目录服务器完成的,所以不用担心在客户端的应用程序上是否要进行安全检查。
LDAP对于这样存储这样的信息最为有用,也就是数据需要从不同的地点读取,但是不需要经常更新。例如,这些信息存储在LDAP目录中是十分有效的:
l 公司员工的电话号码簿和组织结构图
l 客户的联系信息
l 计算机管理需要的信息,包括NIS映射、email假名,等等
l 软件包的配置信息
l 公用证书和安全密匙
什么时候该用LDAP存储数据?
大多数的LDAP服务器都为读密集型的操作进行专门的优化。因此,当从LDAP服务器中读取数据的时候会比从专门为OLTP优化的关系型数据库中读取数据快一个数量级。也是因为专门为读的性能进行优化,大多数的LDAP目录服务器并不适合存储需要需要经常改变的数据。例如,用LDAP服务器来存储电话号码是一个很好的选择,但是它不能作为电子商务站点的数据库服务器。
如果下面每一个问题的答案都是“是”,那么把数据存在LDAP中就是一个好主意。
l 需要在任何平台上都能读取数据吗?
l 每一个单独的记录项是不是每一天都只有很少的改变?
l 可以把数据存在平面数据库(flat database)而不是关系型数据库中吗?换句话来说,也就是不管什么范式不范式的,把所有东西都存在一个记录中(差不多只要满足第一范式)。
最后一个问题可能会唬住一些人,其实用平面数据库去存储一些关系型的数据也是很一般的。例如,一条公司员工的记录就可以包含经理的登录名。用LDAP来存储这类信息是很方便的。一个简单的判断方法:如果可以把保数据存在一张张的卡片里,就可以很容易地把它存在LDAP目录里。
LDAP目录树的结构
LDAP目录以树状的层次结构来存储数据。如果你对自顶向下的DNS树或UNIX文件的目录树比较熟悉,也就很容易掌握LDAP目录树这个概念了。就象DNS的主机名那样,LDAP目录记录的标识名(Distinguished Name,简称DN)是用来读取单个记录,以及回溯到树的顶部。后面会做详细地介绍。
为什么要用层次结构来组织数据呢?原因是多方面的。下面是可能遇到的一些情况:
l 如果你想把所有的美国客户的联系信息都“推”到位于到西雅图办公室(负责营销)的LDAP服务器上,但是你不想把公司的资产管理信息“推”到那里。
l 你可能想根据目录树的结构给予不同的员工组不同的权限。在下面的例子里,资产管理组对“asset-mgmt”部分有完全的访问权限,但是不能访问其它地方。
l 把LDAP存储和复制功能结合起来,可以定制目录树的结构以降低对WAN带宽的要求。位于西雅图的营销办公室需要每分钟更新的美国销售状况的信息,但是欧洲的销售情况就只要每小时更新一次就行了。
刨根问底:基准DN
LDAP目录树的最顶部就是根,也就是所谓的“基准DN”。基准DN通常使用下面列出的三种格式之一。假定我在名为FooBar的电子商务公司工作,这家公司在Internet上的名字是foobar.com。
o="FooBar, Inc.", c=US
(以X.500格式表示的基准DN)
在这个例子中,o=FooBar, Inc. 表示组织名,在这里就是公司名的同义词。c=US 表示公司的总部在美国。以前,一般都用这种方式来表示基准DN。但是事物总是在不断变化的,现在所有的公司都已经(或计划)上Internet上。随着Internet的全球化,在基准DN中使用国家代码很容易让人产生混淆。现在,X.500格式发展成下面列出的两种格式。
o=foobar.com
(用公司的Internet地址表示的基准DN)
这种格式很直观,用公司的域名作为基准DN。这也是现在最常用的格式。
dc=foobar, dc=com
(用DNS域名的不同部分组成的基准DN)
就象上面那一种格式,这种格式也是以DNS域名为基础的,但是上面那种格式不改变域名(也就更易读),而这种格式把域名:foobar.com分成两部分 dc=foobar, dc=com。在理论上,这种格式可能会更灵活一点,但是对于最终用户来说也更难记忆一点。考虑一下foobar.com这个例子。当foobar.com和gizmo.com合并之后,可以简单的把“dc=com”当作基准DN。把新的记录放到已经存在的dc=gizmo, dc=com目录下,这样就简化了很多工作(当然,如果foobar.com和wocket.edu合并,这个方法就不能用了)。如果LDAP服务器是新安装的,我建议你使用这种格式。再请注意一下,如果你打算使用活动目录(Actrive Directory),Microsoft已经限制你必须使用这种格式。
更上一层楼:在目录树中怎么组织数据
在UNIX文件系统中,最顶层是根目录(root)。在根目录的下面有很多的文件和目录。象上面介绍的那样,LDAP目录也是用同样的方法组织起来的。
在根目录下,要把数据从逻辑上区分开。因为历史上(X.500)的原因,大多数LDAP目录用OU从逻辑上把数据分开来。OU表示“Organization Unit”,在X.500协议中是用来表示公司内部的机构:销售部、财务部,等等。现在LDAP还保留ou=这样的命名规则,但是扩展了分类的范围,可以分类为:ou=people, ou=groups, ou=devices,等等。更低一级的OU有时用来做更细的归类。例如:LDAP目录树(不包括单独的记录)可能会是这样的:
dc=foobar, dc=com
ou=customers
ou=asia
ou=europe
ou=usa
ou=employees
ou=rooms
ou=groups
ou=assets-mgmt
ou=nisgroups
ou=recipes
单独的LDAP记录
DN是LDAP记录项的名字
在LDAP目录中的所有记录项都有一个唯一的“Distinguished Name”,也就是DN。每一个LDAP记录项的DN是由两个部分组成的:相对DN(RDN)和记录在LDAP目录中的位置。
RDN是DN中与目录树的结构无关的部分。在LDAP目录中存储的记录项都要有一个名字,这个名字通常存在cn(Common Name)这个属性里。因为几乎所有的东西都有一个名字,在LDAP中存储的对象都用它们的cn值作为RDN的基础。如果我把最喜欢的吃燕麦粥食谱存为一个记录,我就会用cn=Oatmeal Deluxe作为记录项的RDN。
l 我的LDAP目录的基准DN是dc=foobar,dc=com
l 我把自己的食谱作为LDAP的记录项存在ou=recipes
l 我的LDAP记录项的RDN设为cn=Oatmeal Deluxe
上面这些构成了燕麦粥食谱的LDAP记录的完整DN。记住,DN的读法和DNS主机名类似。下面就是完整的DN:
cn=Oatmeal Deluxe,ou=recipes,dc=foobar,dc=com
举一个实际的例子来说明DN
现在为公司的员工设置一个DN。可以用基于cn或uid(User ID),作为典型的用户帐号。例如,FooBar的员工Fran Smith(登录名:fsmith)的DN可以为下面两种格式:
uid=fsmith,ou=employees,dc=foobar,dc=com
(基于登录名)
LDAP(以及X.500)用uid表示“User ID”,不要把它和UNIX的uid号混淆了。大多数公司都会给每一个员工唯一的登录名,因此用这个办法可以很好地保存员工的信息。你不用担心以后还会有一个叫Fran Smith的加入公司,如果Fran改变了她的名字(结婚?离婚?或宗教原因?),也用不着改变LDAP记录项的DN。
cn=Fran Smith,ou=employees,dc=foobar,dc=com
(基于姓名)
可以看到这种格式使用了Common Name(CN)。可以把Common Name当成一个人的全名。这种格式有一个很明显的缺点就是:如果名字改变了,LDAP的记录就要从一个DN转移到另一个DN。但是,我们应该尽可能地避免改变一个记录项的DN。
定制目录的对象类型
你可以用LDAP存储各种类型的数据对象,只要这些对象可以用属性来表示,下面这些是可以在LDAP中存储的一些信息:
l 员工信息:员工的姓名、登录名、口令、员工号、他的经理的登录名,邮件服务器,等等。
l 物品跟踪信息:计算机名、IP地址、标签、型号、所在位置,等等。
l 客户联系列表:客户的公司名、主要联系人的电话、传真和电子邮件,等等。
l 会议厅信息:会议厅的名字、位置、可以坐多少人、电话号码、是否有投影机。
l 食谱信息:菜的名字、配料、烹调方法以及准备方法。
因为LDAP目录可以定制成存储任何文本或二进制数据,到底存什么要由你自己决定。LDAP目录用对象类型(object classes)的概念来定义运行哪一类的对象使用什么属性。在几乎所有的LDAP服务器中,你都要根据自己的需要扩展基本的LDAP目录的功能,创建新的对象类型或者扩展现存的对象类型。
LDAP目录以一系列“属性对”的形式来存储记录项,每一个记录项包括属性类型和属性值(这与关系型数据库用行和列来存取数据有根本的不同)。下面是我存在LDAP目录中的一部分食谱记录:
dn: cn=Oatmeal Deluxe, ou=recipes, dc=foobar, dc=com
cn: Instant Oatmeal Deluxe
recipeCuisine: breakfast
recipeIngredient: 1 packet instant oatmeal
recipeIngredient: 1 cup water
recipeIngredient: 1 pinch salt
recipeIngredient: 1 tsp brown sugar
recipeIngredient: 1/4 apple, any type
请注意上面每一种配料都作为属性recipeIngredient值。LDAP目录被设计成象上面那样为一个属性保存多个值的,而不是在每一个属性的后面用逗号把一系列值分开。
因为用这样的方式存储数据,所以数据库就有很大的灵活性,不必为加入一些新的数据就重新创建表和索引。更重要的是,LDAP目录不必花费内存或硬盘空间处理“空”域,也就是说,实际上不使用可选择的域也不会花费你任何资源。
作为例子的一个单独的数据项
让我们看看下面这个例子。我们用Foobar, Inc.的员工Fran Smith的LDAP记录。这个记录项的格式是LDIF,用来导入和导出LDAP目录的记录项。
dn: uid=fsmith, ou=employees, dc=foobar, dc=com
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
objectclass: foobarPerson
uid: fsmith
givenname: Fran
sn: Smith
cn: Fran Smith
cn: Frances Smith
telephonenumber: 510-555-1234
roomnumber: 122G
o: Foobar, Inc.
mailRoutingAddress: fsmith@foobar.com
mailhost: mail.foobar.com
userpassword: {crypt}3x1231v76T89N
uidnumber: 1234
gidnumber: 1200
homedirectory: /home/fsmith
loginshell: /usr/local/bin/bash
属性的值在保存的时候是保留大小写的,但是在默认情况下搜索的时候是不区分大小写的。某些特殊的属性(例如,password)在搜索的时候需要区分大小写。
让我们一点一点地分析上面的记录项。
dn: uid=fsmith, ou=employees, dc=foobar, dc=com
这是Fran的LDAP记录项的完整DN,包括在目录树中的完整路径。LDAP(和X.500)使用uid(User ID),不要把它和UNIX的uid号混淆了。
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
objectclass: foobarPerson
可以为任何一个对象根据需要分配多个对象类型。person对象类型要求cn(common name)和sn(surname)这两个域不能为空。persion对象类型允许有其它的可选域,包括givenname、telephonenumber,等等。organizational Person给person加入更多的可选域,inetOrgPerson又加入更多的可选域(包括电子邮件信息)。最后,foobarPerson是为Foobar定制的对象类型,加入了很多定制的属性。
uid: fsmith
givenname: Fran
sn: Smith
cn: Fran Smith
cn: Frances Smith
telephonenumber: 510-555-1234
roomnumber: 122G
o: Foobar, Inc.
以前说过了,uid表示User ID。当看到uid的时候,就在脑袋里想一想“login”。
请注意CN有多个值。就象上面介绍的,LDAP允许某些属性有多个值。为什么允许有多个值呢?假定你在用公司的LDAP服务器查找Fran的电话号码。你可能只知道她的名字叫Fran,但是对人力资源处的人来说她的正式名字叫做Frances。因为保存了她的两个名字,所以用任何一个名字检索都可以找到Fran的电话号码、电子邮件和办公房间号,等等。
mailRoutingAddress: fsmith@foobar.com
mailhost: mail.foobar.com
就象现在大多数的公司都上网了,Foobar用Sendmail发送邮件和处理外部邮件路由信息。Foobar把所有用户的邮件信息都存在LDAP中。最新版本的Sendmail支持这项功能。
Userpassword: {crypt}3x1231v76T89N
uidnumber: 1234
gidnumber: 1200
gecos: Frances Smith
homedirectory: /home/fsmith
loginshell: /usr/local/bin/bash
注意,Foobar的系统管理员把所有用户的口令映射信息也都存在LDAP中。FoobarPerson类型的对象具有这种能力。再注意一下,用户口令是用UNIX的口令加密格式存储的。UNIX的uid在这里为uidnumber。提醒你一下,关于如何在LDAP中保存NIS信息,有完整的一份RFC。在以后的文章中我会谈一谈NIS的集成。
LDAP复制
LDAP服务器可以使用基于“推”或者“拉”的技术,用简单或基于安全证书的安全验证,复制一部分或者所有的数据。
例如,Foobar有一个“公用的”LDAP服务器,地址为ldap.foobar.com,端口为389。Netscape Communicator的电子邮件查询功能、UNIX的“ph”命令要用到这个服务器,用户也可以在任何地方查询这个服务器上的员工和客户联系信息。公司的主LDAP服务器运行在相同的计算机上,不过端口号是1389。
你可能即不想让员工查询资产管理或食谱的信息,又不想让信息技术人员看到整个公司的LDAP目录。为了解决这个问题,Foobar有选择地把子目录树从主LDAP服务器复制到“公用”LDAP服务器上,不复制需要隐藏的信息。为了保持数据始终是最新的,主目录服务器被设置成即时“推”同步。这些种方法主要是为了方便,而不是安全,因为如果有权限的用户想查询所有的数据,可以用另一个LDAP端口。
假定Foobar通过从奥克兰到欧洲的低带宽数据的连接用LDAP管理客户联系信息。可以建立从ldap.foobar.com:1389到munich-ldap.foobar.com:389的数据复制,象下面这样:
periodic pull: ou=asia,ou=customers,o=sendmail.com
periodic pull: ou=us,ou=customers,o=sendmail.com
immediate push: ou=europe,ou=customers,o=sendmail.com
“拉”连接每15分钟同步一次,在上面假定的情况下足够了。“推”连接保证任何欧洲的联系信息发生了变化就立即被“推”到Munich。
用上面的复制模式,用户为了访问数据需要连接到哪一台服务器呢?在Munich的用户可以简单地连接到本地服务器。如果他们改变了数据,本地的LDAP服务器就会把这些变化传到主LDAP服务器。然后,主LDAP服务器把这些变化“推”回本地的“公用”LDAP服务器保持数据的同步。这对本地的用户有很大的好处,因为所有的查询(大多数是读)都在本地的服务器上进行,速度非常快。当需要改变信息的时候,最终用户不需要重新配置客户端的软件,因为LDAP目录服务器为他们完成了所有的数据交换工作。
安全和访问控制
LDAP提供很复杂的不同层次的访问控制或者ACI。因这些访问可以在服务器端控制,这比用客户端的软件保证数据的安全可安全多了。
用LDAP的ACI,可以完成:
l 给予用户改变他们自己的电话号码和家庭地址的权限,但是限制他们对其它数据(如,职务名称,经理的登录名,等等)只有“只读”权限。
l 给予“HR-admins”组中的所有人权限以改变下面这些用户的信息:经理、工作名称、员工号、部门名称和部门号。但是对其它域没有写权限。
l 禁止任何人查询LDAP服务器上的用户口令,但是可以允许用户改变他或她自己的口令。
l 给予经理访问他们上级的家庭电话的只读权限,但是禁止其他人有这个权限。
l 给予“host-admins”组中的任何人创建、删除和编辑所有保存在LDAP服务器中的与计算机主机有关的信息
l 通过Web,允许“foobar-sales”组中的成员有选择地给予或禁止他们自己读取一部分客户联系数据的读权限。这将允许他们把客户联系信息下载到本地的笔记本电脑或个人数字助理(PDA)上。(如果销售人员的软件都支持LDAP,这将非常有用)
l 通过Web,允许组的所有者删除或添加他们拥有的组的成员。例如:可以允许销售经理给予或禁止销售人员改变Web页的权限。也可以允许邮件假名(mail aliase)的所有者不经过IT技术人员就直接从邮件假名中删除或添加用户。“公用”的邮件列表应该允许用户从邮件假名中添加或删除自己(但是只能是自己)。也可以对IP地址或主机名加以限制。例如,某些域只允许用户IP地址以192.168.200.*开头的有读的权限,或者用户反向查找DNS得到的主机名必须为*.foobar.com。
这不过是让你了解一下可以对LDAP目录进行怎样的访问控制,实际上真正实现起来需要做的工作比这多得多。在以后的文章中我会详细地讨论访问控制。