Re: Understanding LDAP structures [LONG]
On Sat, 2003-04-19 at 13:51, Alan Chandler wrote:
... snip ldap questions...
First of all, a quick ldap tutorial.
An entry in an ldap directory is basically a set of key/value pairs. In
theory, those keys could be anything if your ldap server is not
validating the entries. I.e., the following is a perfectly valid entry
in a non-validating server:
cn: My Name
iLikeFrogs: yes
fuzzyRabbits: cute
In addition to the data in the entry, an entry also has to have a
name. Think of it as a filesystem: there's two important pieces of
information in the filesystem, the file's name and the file's
contents. In LDAP, the name is called the "distinguished name", or DN
(this is the name that distinguishes this entry from all others).
The DN of the above entry could be
something=foo, somethingelse=bar, andsomethingelse=bat
Note that nothing in the DN actually matches the contents of the entry
above. This is also technically OK, although I believed that later
versions of openldap have started disallowing this. Also, you read the
path from right to left, so 'andsomethingelse=bat' is the top of the
hierarchy.
Also, just like your filesystem needs a root name (/), so does an LDAP
directory. Since there are thousands of LDAP directories in the world,
they can't all use /, so you have to pick something else. The current
practice is to use dc=mydomain, dc=com (assuming that your domain name
is mydomain.com; dc means domain component). This is a guideline, and is
important if your directory will ever merge with someone else's. But,
you don't have to use your domain name; you can choose anything. For
example, using 'o=My House' is a perfectly valid root. The technical
name for this root is the "Base Distinguished Name" or BaseDN.
Getting back to the contents of a directory entry, it's usually bad
practice to allow any king of data in there, because mistakes can be
made, and inconsistencies can be found. Thus, enter the schema. The
schema just describes what data can be stored in the directory. An LDAP
schema describes two things:
1. What kind of attributes are allowed. This is things like cn, ou, etc,
plus what syntax they have, how the should be compared (i.e., case
sensitive or not) and a bunch of other stuff.
2. What king of objects are allowed. This is things like
organizationalUnit, country, locality, etc.
A schema definition starts by defining the attributes, then defining the
object classes. An object class tells ldap what attributes are allowed
in that class. For example, the country object class requires the 'c'
(country) attribute, and also allows the 'searchGuide' and 'description'
attributes.
If your ldap server is enforcing a schema, all entries must belong to at
least one object class. This is what the entry's objectClass attribute
is for. Second, for each object class that the entry belongs to, it will
be required to have certain attributes (specified in the class
definition), it may be allowed to have certain other optional
attributes, and it is not allowed to have any attributes that the object
classes don't allow.
You can use any schema you want, but the standard ldap schema is
typically what you want to use. In Debian, this is defined in
slapd.conf, which in turn includes files in /etc/ldap/schema. The most
important one is core.schema, which codifies the Internet RFC's for LDAP
schemas. Other interesting ones are inetorgperson.schema and nis.schema.
Object classes allow inheritance, and in the standard schema, every
object class inherits from a class called 'top'. For you, the most
interesting object class is probably inetOrgPerson, which describes a
person in an organization that's connected to the Internet.
inetOrgPerson allows a whole bunch of attributes, including mail,
givenName, homePhone, etc. In addition, it inherits from
'organizationalPerson', which allows a whole bunch of other attributes,
including street, ou (organizational unit, i.e., department), etc. In
turn, organizationalPerson inherits from 'person' which allows sn
(surname) and cn (common name), and which in turn inberits from 'top'.
Reading a schema file isn't that hard. Skip past all the the
attributetype stuff and find the objectclass definitions. Those list
what attributes an entry in that objectclass must have, and what
attributes it may have. For example, the "person" object class looks
like
objectclass ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
This says that "person" inherits from top, and an entry with objectclass
of "person" must have sn and cn attributes, and may also have
userPassword, telephoneNumber, seeAlso and description attributes. Any
other attributes are not allowed. So, a person could look like:
objectclass: person
sn: Carrigan
cn: Dave Carrigan
userPassword: foobar
I can't have a mail attribute in this entry, because 'person'
objectclass doesn't allow 'mail' attribute. However, all I need to do is
add inetOrgPerson object class to the entry, and this lets me add a
whole bunch new attributes, including mail:
objectclass: person
objectclass: inetOrgPerson
sn: Carrigan
cn: Dave Carrigan
userPassword: foobar
mail: dave@rudedog.org
initials: dhc
Technically, I can lose the objectclass: person, because inetorgperson's
inheritance tree can trace back to person. Some versions of openldap
require both, however, while I believe that later versions will actually
disallow both.
Once you've decided on the contents of the entry, you have to give it a
name. Just like a filesystem, you can go flat (all the files in the root
directory) or you can go deep.
If your directory is small, then just go flat for simplicity's sake. So,
for the above entry, pick one attribute that's likely to be unique, and
use that for its name. Your Base DN is configured in slapd.conf (the
suffix attribute). All names must be rooted at your base DN. Assuming
that I configured my directory with a Base DN of "o=Chez Carrigan" ('o'
means "organization"), then the name of the above entry could be
dn: cn=Dave Carrigan, o=Chez Carrigan
With the above entry, the following names would be just as valid:
dn: sn=Carrigan, o=Chez Carrigan
dn: cn=Dave Carrigan, o=Chez Carrigan
dn: userPassword=foobar, o=Chez Carrigan
dn: mail=dave@rudedog.org, o=Chez Carrigan
dn: initials=dhc, o=Chez Carrigan
Some of these are better choices than others. For example, I don't
recommend using userPassword in the DN :-)
Also, you don't have to use the same attribute with every every entry in
the directory. For example, I could have the following two entries:
dn: cn=Dave Carrigan, o=Chez Carrigan
dn: mail=fred@rudedog.org, o=Chez Carrigan
If you want to go deep, it's just a question of adding more
"subdirectories":
dn: cn=Dave Carrigan, ou=Mail Stuff, o=Chez Carrigan
Here, ou is organizationalUnitName, which is commonly used as a
placeholder for lots of different things. You can use any attribute you
want, but ou is usually a good choice.
I seem to recall that later versions of openldap require that you create
the intermediate entries (i.e. you need to create a ou=Mail Stuff
entry):
dn: ou=Mail Stuff, o=Chez Carrigan
objectclass: organizationalUnit
ou: Mail Stuff
For simplicity, don't go deep until you know what you're doing.
Going back to your original queries:
A. Admin access
Create an entry for the administrator:
dn: cn=admin, o=Chez Carrigan
objectClass: organizationalRole
objectClass: simpleSecurityObject
cn: admin
userPassword: somepass
I use organizationalRole because I need a cn attribute, and I use
simpleSecurityObject because I need a userPassword attribute.
Second, in slapd.conf, set an acl on that entry so that it can change
stuff in the directory:
access to * by dn="cn=admin,o=Chez Carrigan" write by * read
B. Samba general account
I haven't done anything with ldap and samba, so I don't know.
C. Unix accounts
You will need to set up your nsswitch.conf and pam.d stuff to use ldap,
plus you need to create ldap entries with object classes of posixAccount
and shadowAccount, defined in nis.schema, plus create posixGroup entries
to represent the unix groups. A lot depends on which software you're
planning to use. For example, cyrus imap uses saslauthd, which can be
configured with a ldap backend, and doesn't use pam at all.
D. Mail forwarding
Very dependent on your mail software. I use Postfix in conjunction with
the inetLocalMailRecipient schema to control delivery. Every mail
address resolves to either a standard RFC822 address, or it resolves to
name@local.transport. The relevant fragment of the ldap entry for
forwarding mail is
dn: mailLocalAddress=unclejoe@rudedog.org, o=Chez Carrigan
objectClass: inetlocalmailrecipient
mailLocalAddress: unclejoe@rudedog.org
mailRoutingAddress: unclej@some.otherisp.com
The relevant fragment for local delivery is
dn: cn=Dave Carrigan
objectClass: inetlocalmailrecipient
mailLocalAddress: dave@rudedog.org
mailRoutingAddress: dave@local.cyrus
The relevant fragment of /etc/postfix/transport is
local.cyrus lmtp:unix:/var/spool/cyrus/socket/lmtp
I define a bunch of other transports, such as local.file,
local.autoresponder, etc., and
The relevant fragment of /etc/postfix/main.cf is
virtual_maps=ldap:ldapvdomains
ldapvdomains_server_host=pern
ldapvdomains_search_base=o=Chez Carrigan
ldapvdomains_query_filter=(&(|(objectclass=inetlocalmailrecipient)(objectclass=groupofuniquenames))(maillocaladdress=%s))
ldapvdomains_domain=hash:/etc/postfix/ldap-domains
ldapvdomains_result_attribute=mailroutingaddress,mgrprfc822mailmember
ldapvdomains_special_result_attribute=member,uniquemember
And /etc/postfix/ldap-domains contains
rudedog.org rudedog.org
Before setting up your mail software to use ldap for mail routing, you
will definitely need to get a solid grasp on ldap and your mail
software, because there is no real standard in that area.
E. Web access.
With Apache, you will need something like auth_ldap at
http://www.rudedog.org/auth_ldap/ (shameless plug). The Debian package
is named libapache-auth-ldap. I usually do something like this in
httpd.conf:
AuthLDAPUrl ldap:://ldap.rudedog.org/o=Chez Carrigan?cn??ou=Protected Area 1
require valid-user
Then, the fragment of the ldap entry looks like:
dn: cn=Dave Carrigan, o=Chez Carrigan
...
ou: Protected Area 1
To sign on to Apache, I use my cn (Dave Carrigan) for my user name.
F. Complicated ssh stuff with keys.
Wait a while until you understand ldap better :-)
G. Address book.
This is just a question of adding inetOrgPerson entries for anyone you
want in your address book. Give them extra ou entries in order to
classify them in other ways.
-----
As a postscript, in case you're interested, here's my LDAP entry at work
that covers a lot of the above stuff. It does include attributes from
locally-created schemas, in addition to some of the standard
schemas, so just ignore the pda* attributes and object classes. I've
also munged the mail addresses to thwart spam harvesters.
dn: uid=dave, ou=People, dc=pdaverticals, dc=com
objectClass: pdamailaccount
objectClass: pdaperson
objectClass: posixaccount
objectClass: shadowaccount
objectClass: inetlocalmailrecipient
sn: Carrigan
uid: dave
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/dave
loginShell: /bin/bash
telephoneNumber: +1 000 000 0000
title: Lead Technical Architect
ou: PDA Verticals Personnel
ou: Vertical Database Administrator
gecos: Dave Carrigan
userPassword: <elided>
pdaEmployeeType: staff
givenName: Dave
mailRoutingAddress: dave@local.cyrus
mailLocalAddress: hostmaster@pdaxvxexrxticals.com
mailLocalAddress: domain-administrator@pdaxvxexrxticals.com
mailLocalAddress: domain-technical@pdaxvxexrxticals.com
mailLocalAddress: postmaster@pdaxvxexrxticals.com
mailLocalAddress: postmaster@pxdxaxmd.com
mailLocalAddress: postmaster@pxdxaxre.com
mailLocalAddress: postmaster@pxdxaxjd.com
mailLocalAddress: postmaster@pxdxaxfn.com
mailLocalAddress: dave@pdaxvxexrxticals.com
mailLocalAddress: dave@pxdxaxmd.com
mailLocalAddress: dave@pxdxaxjd.com
mailLocalAddress: dave@pxdxaxre.com
mailLocalAddress: dave@pxdxaxfn.com
mailLocalAddress: ca@pdaxvxexrxticals.com
mailLocalAddress: www-data@pdaxvxexrxticals.com
mailLocalAddress: www-data@pxdxaxmd.com
mailLocalAddress: www-data@pxdxaxjd.com
mailLocalAddress: www-data@pxdxaxre.com
mailLocalAddress: www-data@pxdxaxfn.com
mailLocalAddress: dave@qxuxixzapp.com
mailLocalAddress: csmanual@pdaxvxexrxticals.com
mailLocalAddress: security@pdaxvxexrxticals.com
mailLocalAddress: domain-billing@pdaxvxexrxticals.com
mailLocalAddress: domain-billing@pxdxaxmd.com
mailLocalAddress: cricket@pdaxvxexrxticals.com
mailLocalAddress: postgres@pdaxvxexrxticals.com
mailLocalAddress: csbounces@pdaxvxexrxticals.com
pdalegalName: David
mail: dave@pdaxvxexrxticals.com
cn: Dave Carrigan
cn: David Carrigan
dn: cn=dave, ou=Groups, dc=pdaverticals, dc=com
objectClass: posixgroup
cn: dave
gidNumber: 1000
--
Dave Carrigan
Seattle, WA, USA
dave@rudedog.org | http://www.rudedog.org/ | ICQ:161669680
UNIX-Apache-Perl-Linux-Firewalls-LDAP-C-C++-DNS-PalmOS-PostgreSQL-MySQL
Reply to: