Book Read Free

LDAP System Administration

Page 13

by Gerald Carter


  (&(|(sn=smith)(sn=jones))(cn=john*))

  Note that the (cn=john*) search filter matches any cn that begins with "john": it matches cn=john doe as well as cn=johnathon doe.

  Following Referrals with ldapsearch

  By default, the ldapsearch tool shipped with OpenLDAP 2 prints information about referral objects but does not automatically follow them. For example, let's use ldapsearch to list all entries in your directory that possess an ou attribute:

  $ ldapsearch -H ldap://localhost/ -LL -x

  > -b "dc=plainjoe,dc=org" "(ou=*)" ou

  # plainjoe.org

  dn: dc=plainjoe,dc=org

  ou: PlainJoe Dot Org

  # people, plainjoe.org

  dn: ou=people,dc=plainjoe,dc=org

  ou: people

  # Search reference

  # refldap://ldap2.plainjoe.org/ou=hosts,dc=plainjoe,dc=org??sub

  Note that ldapsearch returned the referral value, but not the entries below the ou=hosts,dc=plainjoe,dc=org naming context. This information is obviously useful when you're trying to debug a directory tree that is distributed between several servers, but it's not what you want if you only intend to look up information. To follow the search referral, give the -C (chase referrals) option when you invoke ldapsearch:

  $ ldapsearch -H ldap://localhost/ -LL -x

  > -b "dc=plainjoe,dc=org" "(ou=*)" ou

  # plainjoe.org

  dn: dc=plainjoe,dc=org

  ou: PlainJoe Dot Org

  # people, plainjoe.org

  dn: ou=people,dc=plainjoe,dc=org

  ou: people

  # hosts, plainjoe.org

  dn: ou=hosts,dc=plainjoe,dc=org

  ou: hosts

  Limiting Your Searches

  A production directory can easily grow to thousands or millions of entries—and with such large directories, searches with filters such as (objectclass=*) can put quite a strain on the directory server and generate more output than you want to deal with. Therefore, ldapsearch lets you define limits for both the client and the server that control the amount of time a search is allowed to take and the number of entries it is allowed to return. Table 5-2 lists the ldapsearch parameters that limit the resources required by any search.

  Table 5-2. Command-line parameters for defining search limits in ldapsearch

  Parameter

  Description

  -l integer

  Specifies the number of seconds in real time to wait for a response to a search request. A value of 0 removes the timelimit default in ldap.conf.

  -z integer

  Defines the maximum number of entries to be retrieved as a result of a successful search request. A value of 0 removes the limits set by the sizelimit option in ldap.conf.

  You can also specify limits on the server, in the slapd.conf file. Table 5-3 lists the global parameters that limit searches.

  Table 5-3. OpenLDAP 2 slapd.conf global search limit parameters

  Parameter

  Description

  sizelimit integer

  Defines the maximum number of entries that the server will return to a client when responding to a search request. The default value is 500 entries.

  timelimit integer

  Specifies the maximum number of seconds in real time to be spent when responding to a search request. The default limit is 1 hour (3,600 seconds).

  * * *

  [1] For the full details of representing LDAP searches using strings, read RFC 2254.

  Determining a Server's Capabilities

  Chapter 2 alluded to two new LDAPv3 features: the subschemaSubentry and the rootDSE objects. Both of these objects allow clients to find out information about a previously unknown directory server.

  The rootDSE object contains information about features such as the server naming context, implemented SASL mechanisms, and supported LDAP extensions and controls. LDAPv3 requires that the rootDSE has an empty DN. To list the rootDSE, perform a base-level search using a DN of "". OpenLDAP will provide only values held by the rootDSE if the search requests that operational attributes be returned, so the + character is appended to the search request.

  $ ldapsearch -x -s base -b "" "(objectclass=*)" +

  dn:

  structuralObjectClass: OpenLDAProotDSE

  namingContexts: dc=plainjoe,dc=org

  supportedControl: 2.16.840.1.113730.3.4.2

  supportedControl: 1.3.6.1.4.1.4203.1.10.2

  supportedControl: 1.2.826.0.1.334810.2.3

  supportedExtension: 1.3.6.1.4.1.4203.1.11.3

  supportedExtension: 1.3.6.1.4.1.4203.1.11.1

  supportedExtension: 1.3.6.1.4.1.1466.20037

  supportedFeatures: 1.3.6.1.4.1.4203.1.5.1

  supportedFeatures: 1.3.6.1.4.1.4203.1.5.2

  supportedFeatures: 1.3.6.1.4.1.4203.1.5.3

  supportedFeatures: 1.3.6.1.4.1.4203.1.5.4

  supportedFeatures: 1.3.6.1.4.1.4203.1.5.5

  supportedLDAPVersion: 3

  supportedSASLMechanisms: GSSAPI

  supportedSASLMechanisms: DIGEST-MD5

  supportedSASLMechanisms: CRAM-MD5

  subschemaSubentry: cn=Subschema

  This list can change over time and will vary from server to server. Our example shows us that this server supports:

  StartTLS (OID 1.3.6.1.4.1.1466.20037) and two other extended operations

  ManageDsaIT (OID 2.16.840.1.113730.3.4.2) and two other LDAP controls

  LDAPv3 operations only

  The GSSAPI, DIGEST-MD5, and CRAM-MD5 SASL mechanisms

  A single naming context of "dc=plainjoe,dc=org"

  There may be additional attributes and values, depending on the LDAP server.

  The SubSchemaSubentry attribute specifies the base search suffix for querying the schema supported by the server. This means that clients can verify that the server supports a given matching rule, attribute type, or object class prior to performing an operation that depends on a certain characteristic. The output from the following ldapsearch command shows the kind of information that is in the SubSchemaSubentry tree. Since this tree contains many entries, I've shortened it for convenience.

  $ ldapsearch -D "cn=Manager,dc=plainjoe,dc=org"

  > -w n0pass -x -s base -b "cn=SubSchema"

  > "(objectclass=*)" +

  ldapSyntaxes: ( 1.3.6.1.4.1.1466.115.121.1.26 DESC 'IA5 String' )

  . . .

  matchingRules: ( 2.5.13.2 NAME 'caseIgnoreMatch' SYNTAX

  1.3.6.1.4.1.1466.115.121.1.15 )

  . . .

  attributeTypes: ( 0.9.2342.19200300.100.1.42 NAME ( 'pager' 'pagerTelephoneNumber' )

  EQUALITY telephoneNumberMatch SUBSTR telephoneNumberSubstringsMatch SYNTAX

  1.3.6.1.4.1.1466.115.121.1.50 )

  . . .

  objectClasses: ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn ) MAY

  ( userPassword $ telephoneNumber $ seeAlso $ description ) )

  . . .

  * * *

  Tip

  You can't modify the schema supported by an OpenLDAP directory server by modifying entries contained in the cn=SubSchema tree.

  * * *

  Creating Custom Schema Files for slapd

  There are times when the standard schema files distributed with your LDAP server don't meet the needs of your application. Creating a custom schema file for OpenLDAP is a simple process:

  Assign a unique OID for all new attribute types and object classes.

  Create the schema file and include it in slapd.conf.

  It's also possible to create alternate schema syntaxes and matching rules, but implementing them is beyond the scope of this book; typically, they require implementing a plug-in for the directory server or modifying the server's source code. For more information on this process, you should consult the OpenLDAP source code or your vendor's documentation for other directory servers.

  Chapter 2 described how to obtain a private enterprise number from IANA (see the form at http://www.iana.org/cgi-bin/enterprise.pl and
RFC 3383). When creating new attributes or object classes, it is a good idea to use an OID that is guaranteed to be unique, whether or not the schema will ever be used outside of your organization. The best way to guarantee that the OID is unique is to obtain a private enterprise number and place all your definitions under that number.

  For example, suppose that an LDAP client application requires a new object class based on person. This new object class should contain all of the attributes possessed by the person object, with the addition of the userPassword and mail attributes.

  In order to create this new object, I have allocated the OID arc of 1.3.6.1.4.1.7165.1.1.1 for the new object classes:

  iso (1)

  org (3)

  dod (6)

  internet (1)

  private (4)

  enterprise (1)

  SAMBA.org (7165)

  plainjoe.org (1)

  O'Reilly LDAP Book(1)

  The private enterprise number 7165 has been issued by IANA for use by the Samba developers, the 7165.1 arc has been allocated to the plainjoe.org domain, and 7165.1.1 has been set aside for this book; I can't touch the numbers above 7165.1 in the tree, but I have complete freedom to assign numbers below it as I see fit. I've chosen to allocate 7165.1.1.1 to ldap object classes that I create and 7165.1.1.2 for new attributes. I could put my new objects directly under plainjoe.org, but that might cause problems if I want to create other kinds of objects (for example, private SNMP MIBs):

  SAMBA.org (7165)

  plainjoe.org (1)

  O'Reilly LDAP Book(1)

  |-- objectclasses (1)

  |-- attributeTypes (2)

  Let's call the new object plainjoePerson. Add the following definition to a custom schema file named plainjoe.schema; you'll use this file for all custom objects that you define.

  ## objectclass definition for 'plainjoePerson' depends on core.schema.

  objectclass ( 1.3.6.1.4.1.7165.1.1.1.1 NAME 'plainjoePerson'

  SUP person STRUCTURAL

  MUST (userPassword $ mail) )

  LDAP's object inheritance allows this new object to reuse the existing characteristics of person; you need to add only the new required attributes. If new attributes are defined as well, they must be defined prior to their use in the plainjoePerson object. The new object has to be defined as STRUCTURAL since it is derived from a structural class.

  New attributes can be defined in the same way or even be derived from existing attributes. RFC 2252 should be considered required reading in this case, as it describes the various LDAPv3 syntaxes and matching rules. For example, you could create a new attribute named plainjoePath to store a single, case-sensitive pathname by defining the following in plainjoe.schema:

  ## Store a case-sensitive path to a directory.

  attributetype( 1.3.6.1.4.1.7165.1.1.2.1 NAME 'plainjoePath'

  DESC 'A directory on disk'

  SUBSTR caseExactIA5SubstringsMatch

  EQUALITY caseExactIA5Match

  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )

  * * *

  Tip

  Servers other than OpenLDAP may use a different schema syntax for representing object classes. You should refer to your directory server's vendor documentation for more details. General LDAPv3 schema syntax is described in RFC 2252.

  * * *

  Finally, you need to add an include line in slapd.conf for your new schema file:

  # /usr/local/etc/openldap/slapd.conf

  # Global section

  ## Include the minimum schema required.

  include /usr/local/etc/openldap/schema/core.schema

  ## **NEW**

  ## Include support for special plainjoe objects.

  include /usr/local/etc/openldap/schema/plainjoe.schema

  After restarting slapd, you can now add objects of the type plainjoePerson or include the plainjoePath in entries that use the extensibleObject class.

  SASL and OpenLDAP

  The final section of this chapter explores how to replace the simple authentication used in your current directory server with SASL mechanisms. You will be using the GSSAPI mechanism for Kerberos 5 authentication (RFCs 1510, 2743, and 2478). The examples assume that a Kerberos realm named PLAINJOE.ORG has already been established and that a service principal named ldapadmin has been created. If you are unclear on the details of Kerberos 5, a good place to start would be Kerberos: A Network Authentication System, by Brian Tung (Addison-Wesley), or The Moron's Guide to Kerberos, located at http://www.isi.edu/gost/brian/security/kerberos.html.

  So far, the rootdn and rootpw values used in slapd.conf have appeared similar to:

  rootdn "cn=Manager,dc=plainjoe,dc=org"

  rootpw {SSHA}2aksIaicAvwc+DhCrXUFlhgWsbBJPLxy

  In OpenLDAP 2.1, an SASL ID can be converted to a distinguished name and used for authentication or authorization wherever a normal DN would be appropriate. This includes operations such as defining the updatedn used for replication or the binddn used by a client in a search request. There's one important exception to this rule: don't use an SASL ID as the DN of an entry in the directory. To summarize from Chapter 3, an SASL ID converted to a DN appears as:

  uid=name[,realm=realm],cn=mechanism,cn=auth

  To illustrate how to use SASL as the authentication mechanism, we'll replace the rootdn in our master server's slapd.conf with the Kerberos 5 principal ldapadmin. Following the conversion algorithm just discussed, the new rootdn in slapd.conf will be:

  ## New SASL-based rootdn

  rootdn "uid=ldapadmin,cn=gssapi,cn=auth"

  The rootpw entry can be deleted because authentication for the new rootdn will be done using the SASL GSSAPI mechanism. The OpenLDAP server must possess a valid keytab file containing the key for decrypting tickets transmitted with client requests.[2] Moreover, our tests will assume that the server is configured to use the default realm of PLAINJOE.ORG.

  Once the configuration change has been made, restart slapd. You can then verify that the change has been made correctly by using the ldapadd command to add an entry; the rootdn is currently the only DN allowed to write to the directory.

  To run this test, create a file with an LDIF entry; we'll use the following LDIF entry, stored in /tmp/test.ldif:

  ## Test user to verify that the new rootdn is OK.

  dn: cn=test user,ou=people,dc=plainjoe,dc=org

  cn: test user

  sn: test

  objectclass: person

  To add this entry to the directory, invoke ldapadd with some additional arguments:

  $ kinit ldapadmin@PLAINJOE.ORG

  Password for ldapadmin@PLAINJOE.ORG: password

  $ klist

  Ticket cache: FILE:/tmp/krb5cc_780

  Default principal: ldapadmin@PLAINJOE.ORG

  Valid starting Expires Service principal

  11/28/02 19:20:15 11/29/02 05:20:15 krbtgt/PLAINJOE.ORG@PLAINJOE.ORG

  $ ldapmodify -a -H ldap://master.plainjoe.org/

  > -f testuser.ldif

  SASL/GSSAPI authentication started

  SASL username: ldapadmin@PLAINJOE.ORG

  SASL SSF: 56

  SASL installing layers

  adding new entry "cn=test user,ou=people,dc=plainjoe,dc=org"

  $ klist

  Ticket cache: FILE:/tmp/krb5cc_780

  Default principal: ldapadmin@PLAINJOE.ORG

  Valid starting Expires Service principal

  11/28/02 19:20:15 11/29/02 05:20:15 krbtgt/PLAINJOE.ORG@PLAINJOE.ORG

  11/28/02 19:23:34 11/29/02 05:20:15 ldap/garion.plainjoe.org@PLAINJOE.ORG

  If the server does not support the particular mechanism needed, GSSAPI in this case, authentication will fail. The -Y option can be used to specify an SASL authentication mechanism rather than letting the client and server attempt to negotiate a valid type that is supported by both. As seen earlier, the client can obtain a list of the mechanisms that the server supports by querying the server's rootDSE and viewing the values of the supportedSASLMechanisms attribut
e.

  After becoming accustomed to SASL user IDs, you can incorporate them into the ACLs defined in slapd.conf. Following the rule that an SASL ID can be used anywhere a DN is used to represent an authenticated user, SASL IDs can follow the by keyword in an ACL definition. For example, the following definition allows the Kerberos principal jerry to edit the mail attribute for all users in the people organizational unit:

  access to dn=".*,ou=people,dc=plainjoe,dc=org" attrs=mail

  by "uid=jerry,cn=gssapi,cn=auth" write

  * * *

  [2] More information on generating keytab files can be found on the kadmin(8) manpage.

  Part II. Application Integration

  Chapter 6

  Chapter 7

  Chapter 8

  Chapter 9

  Chapter 10

  Chapter 6. Replacing NIS

  One of LDAP's chief advantages is its ability to consolidate multiple directory services into one. This chapter examines the pros and cons of using LDAP as a replacement for Sun's Network Information Service (NIS). NIS is used primarily by Unix clients to centralize management of user information and passwords, hostnames and IP addresses, automount maps (files that control the mounting of remote file systems), and other administrative information. NIS clients for other operating systems, such as Windows NT 4.0, exist, though they aren't particularly common.[1]

  While the focus of this chapter is using an LDAP directory as a replacement for NIS domains, many other tools are used to distribute management information on Unix systems; for example, many sites use rsync(1) to push administrative files, such as /etc/passwd, to client machines. While this chapter assumes that you are replacing NIS with an LDAP directory, adapting these techniques I present to other schemes for sharing the data in /etc/passwd, /etc/hosts, and other key files should be straightforward:

 

‹ Prev