6. Server configuration - creating the Kerberos realm

Note

Throughout this HOWTO we use an example.com organization. This must be substituted for an appropriate value.

6.1. OpenLDAP

6.1.1. Basic configuration

First of all we must edit the file /etc/openldap/slapd.conf, so we make the initial configuration of our LDAP server and create our database.

The modifications we have made to the default configuration include the following: inclusion of several schemes to be used by the server, some basic security restrictions, location of certificates to enable SSL encrypted connections, and definition of our database:

# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.23.2.8 2003/05/24 23:19:14 kurt Exp $
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include     /etc/openldap/schema/core.schema
include     /etc/openldap/schema/cosine.schema
include     /etc/openldap/schema/inetorgperson.schema
include     /etc/openldap/schema/java.schema
include     /etc/openldap/schema/krb5-kdc.schema
include     /etc/openldap/schema/nis.schema
                                                                                                                                       
# Define global ACLs to disable default read access.
                                                                                                                                       
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral   ldap://root.openldap.org
                                                                                                                                       
pidfile     /var/run/openldap/slapd.pid
argsfile    /var/run/openldap/slapd.args
                                                                                                                                       
# Load dynamic backend modules:
# modulepath    /usr/lib/openldap/openldap
# moduleload    back_bdb.la
# moduleload    back_ldap.la
# moduleload    back_ldbm.la
# moduleload    back_passwd.la
# moduleload    back_shell.la
                                                                                                                                       
# Sample security restrictions
#   Require integrity protection (prevent hijacking)
#   Require 112-bit (3DES or better) encryption for updates
#   Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64
security simple_bind=64
                                                                                                                                       
# Sample access control policy:
#   Root DSE: allow anyone to read it
#   Subschema (sub)entry DSE: allow anyone to read it
#   Other DSEs:
#       Allow self write access
#       Allow authenticated users read access
#       Allow anonymous users to authenticate
#   Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
#   by self write
#   by users read
#   by anonymous auth
#
# if no access controls are present, the default policy is:
#   Allow read by all
#
# rootdn can always write!
access to dn.base="" by * read
access to dn.base="cn=Subschema" by * read
access to *
    by self write
    by users read
    by anonymous auth
    by * none
                                                                                                                                       
# SSL/TLS configuration
TLSCACertificatePath    /etc/ssl/certs
TLSCertificateFile      /etc/openldap/ssl/ldap.example.com.pem
TLSCertificateKeyFile   /etc/openldap/ssl/ldap.example.com.key

# Misc options
# Maximum number of entries to return from a search operation. Useful
# to prevent trolling of directory by spammers, etc.
sizelimit   20
# Maximum size of the primary thread pool.
threads     8
# Allows acceptance of LDAPv2 bind requests (required for mozilla)
allow bind_v2
                                                                                                                                       
#######################################################################
# ldbm database definitions
#######################################################################

include     /etc/openldap/example.conf

Important

Suitable certificates must have been created and placed in the given directory.

6.1.2. Database configuration

Next we edit the file /etc/openldap/example.conf, containing the definition of our database:

#
# Example Corporation database configuration
#

database    bdb
suffix      "dc=example,dc=com"
rootdn      "cn=manager,dc=example,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoid.  See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw      {MD5}gRUck5diiA7A3fCFN0+mDg==

# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd/tools. Mode 700 recommended.
directory   /var/lib/openldap-example

# Indexes to maintain
index   default     eq,pres
index   objectClass             eq
index   cn,sn,givenname,mail    eq,pres,sub
index   uid,uidNumber,gidNumber
#index  memberUid,uniqueMember  -- This version of OpenLDAP does not support indexing of uniqueMember
index   memberUid
index   krb5PrincipalName,krb5PrincipalRealm

# SASL configuration
sasl_host   ldap.example.local
sasl_realm  EXAMPLE.COM

# Clear text password, as we will be using {SASL}principal@REALM
password-hash {CLEARTEXT}

# ACLs
#include /etc/openldap/example.access.conf

Caution

Make sure you use the canonical name of the machine in sasl-host. Otherwise OpenLDAP won't be able to offer GSSAPI authentication.

Note

You may obtain a password as the one shown in rootpw using the command slappasswd -h {MD5}. Output from that command must be copied and pasted without modification in the configuration file. We will use this administration user and password only until we have done the initial data loading so we can authenticate using Kerberos.

Note

It is very important to define correct indexes so we get a decent performance in the database lookups. You may notice you have lacking indexes whenever you get a line like the following in your logs:

Aug 17 11:10:00 server slapd[7346]: <= bdb_equality_candidates: (memberUid) index_param failed (18)

In this case we had a lacking equality index for the memberUid attribute.

Note

At the end of the configuration file we include an additional file containing the access configuration for our database. Right now we will use the default configuration. Proper ACLs will be shown after.

The directory containing our database must exist and must be accessible only to the LDAP user and group:

server root # mkdir /var/lib/openldap-example
server root # chown ldap:ldap /var/lib/openldap-example
server root # chmod 700 /var/lib/openldap-example

No extra steps are needed: once we start the slapd server the database will be automatically created.

6.1.3. Service configuration

Configuration of services to be started is made editing the file /etc/conf.d/slapd. Here we will activate the following services: ldap, ldaps, and ldap using unix socket:

# conf.d file for the openldap-2.1 series
#
# To enable both the standard unciphered server and the ssl encrypted
# one uncomment this line or set any other server starting options
# you may desire.
#
OPTS="-h 'ldap:// ldaps:// ldapi://'"

Note

The default configuration provided by Gentoo places the LDAP unix socket in /var/run/openldap/slapd.sock. However, Heimdal expects to find this socket in its default location (/var/lib/ldapi) and this location is hard wired. That's why we must change this to the default location, deleting the location provided in the default configuration file.

6.1.4. Initial database creation

In order to create our database we must start the LDAP server. We also add it to the services run on boot up:

server root # /etc/init.d/slapd start
server root # rc-update add slapd default

Caution

All the mentioned configuration files must be accessible to the LDAP user. Otherwise we'll have problems starting the service.

Note

Before accessing the LDAP directory we must check the configuration included in /etc/openldap/ldap.conf so they point to the server we are installing. This way we won't be forced to include this information in every invocation of the LDAP tools. It should contain something like this:

BASE    dc=example,dc=com
URI     ldap://ldap.example.com
TLS_CACERTDIR   /etc/ssl/certs
6.1.4.1. Basic structure

We first create our basic structure. We will have a root for our directory, and then several branches containing groups, system accounts and people. In order to create this basic structure we first edit a file structure.ldif containing the following:

# Organization
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
dc: example
description: The example corporation
o: Example Corporation Inc.

# Kerberos only principals (admin accounts, hosts,...)
dn: ou=kerberos,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: kerberos
description: Kerberos only principals

# Groups
dn: ou=group,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: group
description: Groups in example

# System related accounts
dn: ou=system,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: system
description: System accounts

# People
dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: people
description: People in example

Now we import this into LDAP:

server root # ldapadd -x -D "cn=manager,dc=example,dc=com" -W -f structure.ldif
6.1.4.2. Groups

Next we will be creating (importing) the groups we have in our /etc/group file. We must create a file containing the following entries, one per group, named group.ldif:

dn: cn=root,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: root
gidNumber: 0

dn: cn=bin,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: bin
gidNumber: 1
memberUid: daemon
memberUid: root

dn: cn=daemon,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: daemon
gidNumber: 2
memberUid: bin
memberUid: root

dn: cn=sys,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: sys
gidNumber: 3
memberUid: adm
memberUid: bin
memberUid: root

dn: cn=adm,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: adm
gidNumber: 4
memberUid: daemon
memberUid: root

dn: cn=tty,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: tty
gidNumber: 5

dn: cn=disk,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: disk
gidNumber: 6
memberUid: adm
memberUid: root

dn: cn=lp,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: lp
gidNumber: 7

dn: cn=mem,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: mem
gidNumber: 8

dn: cn=kmem,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: kmem
gidNumber: 9

dn: cn=wheel,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: wheel
gidNumber: 10
memberUid: root

dn: cn=floppy,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: floppy
gidNumber: 11
memberUid: root

dn: cn=mail,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: mail
gidNumber: 12

dn: cn=news,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: news
gidNumber: 13

dn: cn=uucp,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: uucp
gidNumber: 14

dn: cn=man,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: man
gidNumber: 15

dn: cn=cron,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: cron
gidNumber: 16

dn: cn=console,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: console
gidNumber: 17

dn: cn=audio,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: audio
gidNumber: 18

dn: cn=cdrom,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: cdrom
gidNumber: 19

dn: cn=dialout,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: dialout
gidNumber: 20
memberUid: root

dn: cn=ftp,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: ftp
gidNumber: 21

dn: cn=sshd,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: sshd
gidNumber: 22

dn: cn=at,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: at
gidNumber: 25

dn: cn=tape,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: tape
gidNumber: 26
memberUid: root

dn: cn=video,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: video
gidNumber: 27
memberUid: root

dn: cn=squid,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: squid
gidNumber: 31

dn: cn=gdm,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: gdm
gidNumber: 32

dn: cn=xfs,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: xfs
gidNumber: 33

dn: cn=games,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: games
gidNumber: 35

dn: cn=named,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: named
gidNumber: 40

dn: cn=mysql,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: mysql
gidNumber: 60

dn: cn=postgres,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: postgres
gidNumber: 70

dn: cn=cdrw,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: cdrw
gidNumber: 80

dn: cn=apache,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: apache
gidNumber: 81

dn: cn=nut,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: nut
gidNumber: 84

dn: cn=usb,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: usb
gidNumber: 85

dn: cn=vpopmail,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: vpopmail
gidNumber: 89

dn: cn=users,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: users
gidNumber: 100
memberUid: games

dn: cn=nofiles,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: nofiles
gidNumber: 200

dn: cn=qmail,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: qmail
gidNumber: 201

dn: cn=postfix,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: postfix
gidNumber: 207

dn: cn=postdrop,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: postdrop
gidNumber: 208

dn: cn=smmsp,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: smmsp
gidNumber: 209

dn: cn=slocate,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: slocate
gidNumber: 245

dn: cn=portage,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: portage
gidNumber: 250

dn: cn=utmp,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: utmp
gidNumber: 406

dn: cn=nogroup,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: nogroup
gidNumber: 65533

dn: cn=nobody,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: nobody
gidNumber: 65534

dn: cn=ldap,ou=group,dc=example,dc=com
objectClass: posixGroup
objectClass: top
cn: ldap
gidNumber: 439

Note

The file provided contains the groups found in a clean stage3 Gentoo installation with no additional software installed, adding the ldap group. Should your group file differ from the groups included here you must modify this file to reflect your installation.

Warning

Whenever you install any application using portage that creates a new group, you will have to manually add this group to the LDAP directory, as portage uses groupadd to add such a group, and this only adds the group to the /etc/group file.

Now we import this data into the LDAP directory:

server root # ldapadd -x -D "cn=manager,dc=example,dc=com" -W -f group.ldif
6.1.4.3. System accounts

I like to have system and people accounts in different places in the LDAP directory, so they don't mess around. This is completely optional, so you may have all the accounts under the people branch.

First of all, we create a file with our system accounts, name system.ldif:

dn: uid=bin,ou=system,dc=example,dc=com
uid: bin
cn: bin
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 1
gidNumber: 1
homeDirectory: /bin

dn: uid=daemon,ou=system,dc=example,dc=com
uid: daemon
cn: daemon
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 2
gidNumber: 2
homeDirectory: /sbin

dn: uid=adm,ou=system,dc=example,dc=com
uid: adm
cn: adm
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 3
gidNumber: 4
homeDirectory: /var/adm

dn: uid=lp,ou=system,dc=example,dc=com
uid: lp
cn: lp
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 4
gidNumber: 7
homeDirectory: /var/spool/lpd

dn: uid=sync,ou=system,dc=example,dc=com
uid: sync
cn: sync
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/sync
uidNumber: 5
gidNumber: 0
homeDirectory: /sbin

dn: uid=shutdown,ou=system,dc=example,dc=com
uid: shutdown
cn: shutdown
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /sbin/shutdown
uidNumber: 6
gidNumber: 0
homeDirectory: /sbin

dn: uid=halt,ou=system,dc=example,dc=com
uid: halt
cn: halt
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /sbin/halt
uidNumber: 7
gidNumber: 0
homeDirectory: /sbin

dn: uid=mail,ou=system,dc=example,dc=com
uid: mail
cn: mail
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 8
gidNumber: 12
homeDirectory: /var/spool/mail

dn: uid=news,ou=system,dc=example,dc=com
uid: news
cn: news
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 9
gidNumber: 13
homeDirectory: /usr/lib/news

dn: uid=uucp,ou=system,dc=example,dc=com
uid: uucp
cn: uucp
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 10
gidNumber: 14
homeDirectory: /var/spool/uucppublic

dn: uid=operator,ou=system,dc=example,dc=com
uid: operator
cn: operator
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/bash
uidNumber: 11
gidNumber: 0
homeDirectory: /root

dn: uid=man,ou=system,dc=example,dc=com
uid: man
cn: man
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 13
gidNumber: 15
homeDirectory: /usr/man

dn: uid=postmaster,ou=system,dc=example,dc=com
uid: postmaster
cn: postmaster
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 14
gidNumber: 12
homeDirectory: /var/spool/mail

dn: uid=cron,ou=system,dc=example,dc=com
uid: cron
cn: cron
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 16
gidNumber: 16
homeDirectory: /var/spool/cron

dn: uid=ftp,ou=system,dc=example,dc=com
uid: ftp
cn: ftp
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 21
gidNumber: 21
homeDirectory: /home/ftp

dn: uid=sshd,ou=system,dc=example,dc=com
uid: sshd
cn: sshd
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 22
gidNumber: 22
homeDirectory: /dev/null

dn: uid=at,ou=system,dc=example,dc=com
uid: at
cn: at
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 25
gidNumber: 25
homeDirectory: /var/spool/cron/atjobs

dn: uid=squid,ou=system,dc=example,dc=com
uid: squid
cn: Squid
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 31
gidNumber: 31
homeDirectory: /var/cache/squid

dn: uid=gdm,ou=system,dc=example,dc=com
uid: gdm
cn: GDM
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 32
gidNumber: 32
homeDirectory: /var/lib/gdm

dn: uid=xfs,ou=system,dc=example,dc=com
uid: xfs
cn: X Font Server
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 33
gidNumber: 33
homeDirectory: /etc/X11/fs

dn: uid=games,ou=system,dc=example,dc=com
uid: games
cn: games
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 35
gidNumber: 35
homeDirectory: /usr/games

dn: uid=named,ou=system,dc=example,dc=com
uid: named
cn: bind
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 40
gidNumber: 40
homeDirectory: /var/bind

dn: uid=mysql,ou=system,dc=example,dc=com
uid: mysql
cn: mysql
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 60
gidNumber: 60
homeDirectory: /var/lib/mysql

dn: uid=postgres,ou=system,dc=example,dc=com
uid: postgres
cn: postgres
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/bash
uidNumber: 70
gidNumber: 70
homeDirectory: /var/lib/postgresql

dn: uid=apache,ou=system,dc=example,dc=com
uid: apache
cn: apache
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 81
gidNumber: 81
homeDirectory: /home/httpd

dn: uid=nut,ou=system,dc=example,dc=com
uid: nut
cn: nut
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 84
gidNumber: 84
homeDirectory: /var/state/nut

dn: uid=cyrus,ou=system,dc=example,dc=com
uid: cyrus
cn: cyrus
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 85
gidNumber: 12
homeDirectory: /usr/cyrus

dn: uid=vpopmail,ou=system,dc=example,dc=com
uid: vpopmail
cn: vpopmail
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 89
gidNumber: 89
homeDirectory: /var/vpopmail

dn: uid=alias,ou=system,dc=example,dc=com
uid: alias
cn: alias
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 200
gidNumber: 200
homeDirectory: /var/qmail/alias

dn: uid=qmaild,ou=system,dc=example,dc=com
uid: qmaild
cn: qmaild
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 201
gidNumber: 200
homeDirectory: /var/qmail

dn: uid=qmaill,ou=system,dc=example,dc=com
uid: qmaill
cn: qmaill
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 202
gidNumber: 200
homeDirectory: /var/qmail

dn: uid=qmailp,ou=system,dc=example,dc=com
uid: qmailp
cn: qmailp
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 203
gidNumber: 200
homeDirectory: /var/qmail

dn: uid=qmailq,ou=system,dc=example,dc=com
uid: qmailq
cn: qmailq
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 204
gidNumber: 201
homeDirectory: /var/qmail

dn: uid=qmailr,ou=system,dc=example,dc=com
uid: qmailr
cn: qmailr
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 205
gidNumber: 201
homeDirectory: /var/qmail

dn: uid=qmails,ou=system,dc=example,dc=com
uid: qmails
cn: qmails
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 206
gidNumber: 201
homeDirectory: /var/qmail

dn: uid=postfix,ou=system,dc=example,dc=com
uid: postfix
cn: postfix
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 207
gidNumber: 207
homeDirectory: /var/spool/postfix

dn: uid=smmsp,ou=system,dc=example,dc=com
uid: smmsp
cn: smmsp
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 209
gidNumber: 209
homeDirectory: /var/spool/mqueue

dn: uid=portage,ou=system,dc=example,dc=com
uid: portage
cn: portage
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 250
gidNumber: 250
homeDirectory: /var/tmp/portage

dn: uid=guest,ou=system,dc=example,dc=com
uid: guest
cn: guest
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /dev/null
uidNumber: 405
gidNumber: 100
homeDirectory: /dev/null

dn: uid=nobody,ou=system,dc=example,dc=com
uid: nobody
cn: nobody
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /bin/false
uidNumber: 65534
gidNumber: 65534
homeDirectory: /

dn: uid=ldap,ou=system,dc=example,dc=com
uid: ldap
cn: ldap
objectClass: top
objectClass: account
objectClass: posixAccount
loginShell: /dev/null
uidNumber: 439
gidNumber: 439
homeDirectory: /usr/lib/openldap

Caution

Do not add the root user to this file. Keep in mind that we are building a central authentication server, so adding root here would mean that somebody knowing the root password would have root access to every machine in the whole network.

Note

The file provided contains the accounts found in a clean stage3 Gentoo installation with no additional software installed, adding the ldap user. Should your passwd file differ from the accounts included here you must modify this file to reflect your installation.

Warning

Whenever you install any application using portage that creates a new account, you will have to manually add this account to the LDAP directory, as portage uses useradd to add such an account, and this only adds the account to the /etc/passwd file.

Now we import this data into the LDAP directory:

server root # ldapadd -x -D "cn=manager,dc=example,dc=com" -W -f system.ldif
6.1.4.4. People accounts

Next we will create the entries for our users, editing the file people.ldif:

dn: cn=Jose Gonzalez Gomez,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: posixAccount
objectClass: top
objectClass: krb5Principal
objectClass: krb5KDCEntry
krb5PrincipalName: jgonzalez@EXAMPLE.COM
krb5KeyVersionNumber: 1
krb5MaxLife: 86400
krb5MaxRenew: 604800
krb5KDCFlags: 126
cn: Jose Gonzalez Gomez
givenName: Jose
mail: jgonzalez@example.com
sn: Gonzalez Gomez
uid: jgonzalez
uidNumber: 500
gidNumber: 100
homeDirectory: /home/jgonzalez
loginShell: /bin/bash

dn: cn=Antonio Perez Lopez,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: posixAccount
objectClass: top
objectClass: krb5Principal
objectClass: krb5KDCEntry
krb5PrincipalName: aperez@EXAMPLE.COM
krb5KeyVersionNumber: 1
krb5MaxLife: 86400
krb5MaxRenew: 604800
krb5KDCFlags: 126
cn: Antonio Perez Lopez
givenName: Antonio
mail: aperez@example.com
sn: Perez Lopez
uid: aperez
uidNumber: 501
gidNumber: 100
homeDirectory: /home/aperez
loginShell: /bin/bash

Now we import this data into the LDAP directory:

server root # ldapadd -x -D "cn=manager,dc=example,dc=com" -W -f example.ldif

Note

We are creating our first Kerberos principals, but they still lack their password (krb5Key). This password will be set once we configure Kerberos so it's able to access the whole directory to find Kerberos principals. See Setting Kerberos to read the whole directory.

6.2. Heimdal Kerberos

6.2.1. Basic configuration

First we create the configuration file /etc/krb5.conf, with the information relative to the Kerberos domain we will be creating:

[libdefaults]
    ticket_lifetime = 600
    default_realm = EXAMPLE.COM
    default_etypes = des3-hmac-sha1 des-cbc-crc des-cbc-md5
    default_etypes_des = des3-hmac-sha1 des-cbc-crc des-cbc-md5

[realms]
    EXAMPLE.COM = {
    kdc = kerberos.example.local:88
    admin_server = kerberos.example.local:749
    }

[domain_realm]
    .example.local = EXAMPLE.COM
    example.local = EXAMPLE.COM

[kdc]
    database = {
        realm = EXAMPLE.COM
        dbname = ldap:ou=kerberos,dc=example,dc=com
        mkey_file = /var/heimdal/m-key
    }

[logging]
    kdc = SYSLOG
    admin_server = SYSLOG
    default = SYSLOG

6.2.2. Creation of the Kerberos domain

We may have all the keys of our principals encrypted with a master key. In order to create this master key we invoke the kstash command:

server root # kstash
Master key:<type master key>
Verifying - Master key:<type master key>
kstash: writing key to `/var/heimdal/m-key'

Once created the master key we can initialize our domain, issuing the following command:

server root # kadmin -l
kadmin> init EXAMPLE.COM
Realm max ticket life [unlimited]:
Realm max renewable ticket life [unlimited]:
kadmin>

This should have created several entries in our LDAP directory under the system branch.

6.2.3. Password policies

Heimdal provides a pluggable mechanism for controlling password quality. This mechanism may be configured using the following section in /etc/krb5.conf:

[password_quality]
    check_library = library
    check_function = function

However, Heimdal doesn't seem to provide any library for password quality enforcement out of the box.

6.2.4. User creation

Let's change the kadmin/admin password so we may use this principal for administration:

server root # kadmin -l
kadmin> cpw kadmin/admin
kadmin/admin@EXAMPLE.COM's Password:<enter password>
Verifying - kadmin/admin@EXAMPLE.COM's Password:<enter password>
kadmin>

Let's create a user for LDAP administration:

server root # kadmin -l
kadmin> add ldapmaster
Max ticket life [1 day]:
Max renewable life [1 week]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
ldapmaster@EXAMPLE.COM's Password:<enter password>
Verifying - ldapmaster@EXAMPLE.COM's Password:<enter password>
kadmin>

6.2.5. ACL configuration

File /var/heimdal/kadmind.acl:

kadmin/admin@EXAMPLE.COM     all
otheruser@EXAMPLE.COM        all

6.2.6. Kerberos servers

For every network service accepting Kerberos authenticated connections we need to create a principal for the service and then we must extract a service ticket and put it in a keytab. We need to do this in order to provide PAM or SSH authentication:

server root # kadmin -l
kadmin> add --random-key host/kerberos.example.local
Max ticket life [1 day]:
Max renewable life [1 week]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin> ext_keytab host/kerberos.example.local
kadmin>

Caution

It is extremely important to use the canonical name of the machine where the server is located, since Kerberos uses this name to get the service ticket, although we access the service using an alias. If we don't use the canonical name we may face an error like this "GSSAPI Error: Miscellaneous failure (Server not found in Kerberos database)" when we try to access the service.

6.2.7. Checking our Kerberos installation

Once we have reached this point we may init the Kerberos services and add them to the services started on boot up:

server root # /etc/init.d/heimdal-kdc start
server root # /etc/init.d/heimdal-kadmind start
server root # /etc/init.d/heimdal-kpasswdd start
server root # rc-update add heimdal-kdc default
server root # rc-update add heimdal-kadmind default
server root # rc-update add heimdal-kpasswdd default

We may check the service is working properly trying to initialize our credentials cache with one of the previously created users:

server root # kinit kadmin/admin
kadmin/admin@EXAMPLE.COM's Password:<enter password>
kinit: NOTICE: ticket renewable lifetime is 1 hour
server root # klist
Credentials cache: FILE:/tmp/krb5cc_0
        Principal: kadmin/admin@EXAMPLE.COM

  Issued           Expires          Principal
Aug 17 12:07:56  Aug 17 12:17:56  krbtgt/EXAMPLE.COM@EXAMPLE.COM

6.2.8. Setting Kerberos to read the whole directory

Until now we have been working in the ou=kerberos,dc=example,dc=com branch in order to create needed entries for Kerberos to work properly, and to create Kerberos principals that doesn't correspond to real people, as the ldapmaster principal for LDAP administration. Now we must make Kerberos able to access the whole directory so it can find real people under the ou=people,dc=example,dc=com branch. To achieve this, we edit the file /etc/krb5.conf and change dbname in the kdc section to look like this:

[kdc]
    database = {
        realm = EXAMPLE.COM
        dbname = ldap:dc=example,dc=com
        mkey_file = /var/heimdal/m-key
    }

Now we have access to all the principals defined in all the directory branches:

server root # kadmin -l
kadmin> list *
  aperez@EXAMPLE.COM
  changepw/kerberos@EXAMPLE.COM
  default@EXAMPLE.COM
  kadmin/admin@EXAMPLE.COM
  kadmin/changepw@EXAMPLE.COM
  kadmin/hprop@EXAMPLE.COM
  krbtgt/EXAMPLE.COM@EXAMPLE.COM
  ldapmaster@EXAMPLE.COM
  host/kerberos.example.local@EXAMPLE.COM
  ldap/commserver.example.local@EXAMPLE.COM
  jgonzalez@EXAMPLE.COM

Now we can set the password of the users we created in the ou=people branch:

kadmin> cpw jgonzalez
jgonzalez@EXAMPLE.COM's Password:<enter password>
Verifying - jgonzalez@EXAMPLE.COM's Password:<enter password>

6.3. OpenLDAP access configuration

Now we are going to configure a few things in order to provide Kerberos authenticated access to OpenLDAP.

6.3.1. Creation of LDAP service ticket

First we must create a principal for the LDAP service and then export its service ticket to a keytab accessible by OpenLDAP:

server root # kadmin -l
kadmin> add --random-key ldap/ldap.example.local
Max ticket life [1 day]:
Max renewable life [1 week]:
Principal expiration time [never]:
Password expiration time [never]:
Attributes []:
kadmin> q
server root # kinit kadmin/admin
kadmin/admin@EXAMPLE.COM's Password:<enter password>
kinit: NOTICE: ticket renewable lifetime is 1 hour
server root # ktutil -k /etc/openldap/ldap.keytab get ldap/commserver.example.local
server root # chown root:ldap /etc/openldap/ldap.keytab
server root # chmod 640 /etc/openldap/ldap.keytab

Caution

In order to authenticate against OpenLDAP using SASL/GSSAPI we have to create this service ticket. It is extremely important to use the canonical name of the machine where the LDAP server is located, since Kerberos uses this name to get the service ticket, although we access the service using an alias. If we don't use the canonical name we may face an error like this "GSSAPI Error: Miscellaneous failure (Server not found in Kerberos database)" when we try to access the service.

Next we must tell OpenLDAP/SASL where to find the keytab containing its service ticket. To do so, we edit the file /etc/conf.d/slapd, adding the KRB5_KTNAME environment variable. This file would look like this:

# conf.d file for the openldap-2.1 series
#
# To enable both the standard unciphered server and the ssl encrypted
# one uncomment this line or set any other server starting options
# you may desire.
#
OPTS="-h 'ldap:// ldaps:// ldapi://'"

# Kerberos keytab file
export KRB5_KTNAME=/etc/openldap/ldap.keytab

Next we may restart OpenLDAP for changes to take effect:

server root # /etc/init.d/slapd restart

6.3.2. Checking authentication services offered by OpenLDAP/SASL

Now we will check the SASL authentication services offered by OpenLDAP, both with encrypted and unencrypted communications. We should get something like this:

server root # ldapsearch -H ldap://ldap.example.local/ -x -b "" -s base -LLL supportedSASLMechanisms
dn:
supportedSASLMechanisms: NTLM
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: CRAM-MD5

server root # ldapsearch -H ldap://ldap.example.local/ -x -b "" -s base -LLL -ZZ supportedSASLMechanisms
dn:
supportedSASLMechanisms: NTLM
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: PLAIN
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: CRAM-MD5
 
server root # ldapsearch -H ldaps://ldap.example.local/ -x -b "" -s base -LLL supportedSASLMechanisms
dn:
supportedSASLMechanisms: NTLM
supportedSASLMechanisms: LOGIN
supportedSASLMechanisms: PLAIN
supportedSASLMechanisms: GSSAPI
supportedSASLMechanisms: DIGEST-MD5
supportedSASLMechanisms: CRAM-MD5

6.3.3. Single sign on while accessing OpenLDAP

OpenLDAP tools, when compiled with Kerberos support, will use GSSAPI as the default authentication mechanism. So in order to check if this functionality is working we have just to issue an ldapsearch, as long as we have our credentials cache correctly initialized:

server root # kinit ldapmaster
ldapmaster@EXAMPLE.COM's Password:<enter password>
kinit: NOTICE: ticket renewable lifetime is 1 week
server root # ldapsearch
SASL/GSSAPI authentication started
SASL username: ldapmaster@EXAMPLE.COM
SASL SSF: 56
SASL installing layers
# extended LDIF
#
# LDAPv3
# base <> with scope sub
# filter: (objectclass=*)
# requesting: ALL
#
........

The first four lines tell us that GSSAPI authentication has been successful. This example shows the single sign on capability offered by Kerberos.

6.3.4. Mapping authentication identities to LDAP entries

If we authenticate ourselves against the directory server using GSSAPI, we will have what is known as an authentication identity. This identity is in the name space of the SASL authentication mechanism, not in the name space of the LDAP server:

server root # ldapwhoami
SASL/GSSAPI authentication started
SASL username: ldapmaster@EXAMPLE.COM
SASL SSF: 56
SASL installing layers
dn:uid=ldapmaster,cn=gssapi,cn=auth
server root # ldapwhoami -Y EXTERNAL -H ldapi://
SASL/EXTERNAL authentication started
SASL username: uidNumber=0+gidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn:uidnumber=0+gidnumber=0,cn=peercred,cn=external,cn=auth

The dn uses to be of the form

uid=<username>,cn=<realm>,cn=<mechanism>,cn=auth

or

uid=<username>,cn=<mechanism>,cn=auth

if the mechanism doesn't understand the concept of realms, or the authentication took place using the default realm.

It's convenient to map these authentication identities to LDAP entries, so we may later assign permissions in our ACLs based on those entries. To do so, we include the following in /etc/openldap/example.conf:

# Mapping of SASL authentication identities to LDAP entries
sasl-regexp
    uid=(.+),cn=(.+),cn=.+,cn=auth
    ldap:///dc=$2,dc=com??sub?(|(uid=$1)(cn=$1@$2))
sasl-regexp
    uid=(.+),cn=.+,cn=auth
    ldap:///dc=example,dc=com??sub?(|(uid=$1)(krb5PrincipalName=$1@EXAMPLE.COM))
sasl-regexp
    uidnumber=0\\\+gidnumber=0,cn=peercred,cn=external,cn=auth
    cn=ldapmaster@circuitcat.com,ou=kerberos,dc=circuitcat,dc=com

This basically maps any authentication identity to the LDAP entry containing an uid or krb5PrincipalName equal to the identity provided. The last expression maps connections made to ldapi:// by root to the ldap administrator account.

Note

For a rather deep discussion about mapping identities to entries, see the OpenLDAP 2.2 Administrator Guide.

After doing this, and restarting the server, we obtain the following:

server root # ldapwhoami
SASL/GSSAPI authentication started
SASL username: ldapmaster@EXAMPLE.COM
SASL SSF: 56
SASL installing layers
dn:cn=ldapmaster@example.com,ou=kerberos,dc=example,dc=com
server root # ldapwhoami -Y EXTERNAL -H ldapi://
SASL/EXTERNAL authentication started
SASL username: uidNumber=0+gidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn:cn=ldapmaster@example.com,ou=kerberos,dc=example,dc=com

6.3.5. Creating a proxy for NSS

We are now going to create a LDAP entry that will act as a proxy for the NSS, so attributes related to Unix/Linux authorization may be accessed only using this proxy. First we create the entry for our proxy, editing the file nssproxy.ldif:

dn: cn=nssproxy@example.com,ou=kerberos,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: krb5Principal
objectClass: krb5KDCEntry
krb5PrincipalName: nssproxy@EXAMPLE.COM
krb5KeyVersionNumber: 1
krb5MaxLife: 86400
krb5MaxRenew: 604800
krb5KDCFlags: 126
cn: nssproxy@example.com
sn: nssproxy@example.com
userPassword: {SASL}nssproxy@EXAMPLE.COM

Note

nss_ldap is able to do Kerberos authentication, but this should mean getting and renewing a ticket without user interaction. It's far easier to setup nss_ldap using simple bind, and this way we'll also show how to setup simple bind authentication when accessing the directory.

Now we import this data into the LDAP directory:

server root # ldapadd -x -D "cn=manager,dc=example,dc=com" -W -f nssproxy.ldif

Now we must assign a password to the principal we have just created:

server root # kadmin -l
kadmin> cpw nssproxy
nssproxy@EXAMPLE.COM's Password:<enter password>
Verifying - nssproxy@EXAMPLE.COM's Password:<enter password>

6.3.6. Configuring SASL and LDAP to allow simple bind authentication

Warning

The whole purpose of this HOWTO is setting up a central authentication server using Kerberos as the key component of the installation. We use Kerberos because is meant to provide secure authentication in untrusted environments.

We are now going to configure SASL and LDAP to allow simple bind authentication against the LDAP server. What does this mean? This means we will be sending the clear text password over the wire!!! Why are we doing this? Because unfortunately not all clients support SASL/GSSAPI authentication, so we must provide other means of authentication for those clients.

I think there's no need to stress the importance of making such an authentication under the context of a secured connection, for instance, using SSL/TLS, and giving this access only when strictly needed. If we don't, we are blowing up the whole security infrastructure we are setting up.

Simple bind authentication is a mechanism offered by OpenLDAP so users can authenticate to the directory server providing a bind DN and a password. OpenLDAP then compares the password provided with the password stored in the userPassword attribute of the provided DN. If they match, the user gets authenticated, and proper permissions are given based on provided ACLs.

Caution

Passwords in OpenLDAP may be stored using some hash, but passwords provided in a simple bind operation are always transmitted as clear text. Be sure you have a security option with at least the following included in /etc/openldap/slapd.conf in order to disallow simple binds in unprotected connections:

security simple_bind=64

We will be using the SASL authentication daemon (saslauthd) to authenticate users trying to bind to our directory. We want to keep just one password database, so we'll configure saslauthd so it contacts Kerberos to do user/password verification.

Note

This setup may lead to performance problems. Keep in mind that every simple bind authentication will lead to a Kerberos authentication. This may get worse if you use this setup to authenticate not only OpenLDAP users but users of other services, as your SMTP or POP/IMAP server. The solution to these problems is to use another authentication mechanism instead of Kerberos. In that case you will need a separate password database for users authenticating through saslauthd.

Which solution is better? That depends on you: you may prefer a greater performance making saslauthd authenticate against its native database, or you may prefer ease of maintenance having only one password database. In our case we have chosen the second option.

First we must edit the file /etc/sasl2/slapd.conf, so simple bind authentication is redirected to saslauthd:

pwcheck_method:saslauthd

Then we must configure saslauthd so it checks users and passwords against Kerberos. This is done in /etc/conf.d/saslauthd:

SASLAUTHD_OPTS="${SASLAUTH_MECH} -a kerberos5"

Now we must start the saslauthd daemon. We also add it to the services run on boot up:

server root # /etc/init.d/saslauthd start
server root # rc-update add saslauthd default

Finally, we must locate every user we want to let authenticate using simple bind, and change their userPassword attribute to {SASL}principal@REALM (substituting principal and REALM for proper values, of course). We have done so with the NSS proxy user we created before, so we may use it to test this functionality:

server root # ldapwhoami -ZZ -x -D "cn=nssproxy@example.com,ou=kerberos,dc=example,dc=com" -W
Enter LDAP Password:<enter password>
dn:cn=nssproxy@example.com,ou=kerberos,dc=example,dc=com

6.3.7. Securing the directory

Once we have mapped authentication identities to LDAP entries we may set suitable ACLs to control who is able to access information stored in our directory service. Firs we must uncomment the line that includes our access configuration in /etc/openldap/example.conf:

# ACLs
include /etc/openldap/example.access.conf

Then we must create the /etc/openldap/example.access.conf file, with the following content:

# Remember that rootdn has always write access
# posixAccount/posixGroup attributes may only be accessible to root/ldapmaster (write) and pamproxy (read)
access to attrs=uid,uidNumber,gidNumber,gecos,homeDirectory,loginShell,memberUid
    by dn="cn=pamproxy@circuitcat.com,ou=kerberos,dc=circuitcat,dc=com" read

# This is needed so sasl-regexp/GSSAPI works correctly
access to attrs=krb5PrincipalName
    by anonymous auth

# Kerberos attributes may only be accessible to root/ldapmaster
access to attrs=krb5KeyVersionNumber,krb5PrincipalRealm,krb5EncryptionType,krb5KDCFlags,krb5Key,krb5MaxLife,krb5MaxRenew,krb5PasswordEnd,krb5ValidEnd,krb5ValidStart,krb5RealmNam
    by * none

# We will be using userPassword to provide simple BIND access, so we don't want this to be user editable
access to attrs=userPassword
    by anonymous auth

# Write access to common attributes for users
access to dn.subtree="ou=people,dc=circuitcat,dc=com" attrs=telephoneNumber,facsimileTelephoneNumber,jpegPhoto,homePhone,homePostalAddress
    by self write
    by users read

# Anything else we may have forgotten is writable by admin, and viewable by authenticated users
access to dn.subtree="dc=circuitcat,dc=com"
    by users read

This is a rather simple access configuration file that should be customized for your needs, but that offers a basic security protection.

Note

For a rather deep discussion about OpenLDAP ACLs, see the OpenLDAP 2.2 Administrator Guide.

Now we change the rootdn in /etc/openldap.example.conf and take away the rootpw option:

rootdn      "cn=ldapmaster@example.com,ou=kerberos,dc=example,dc=com"
# Be sure to take away or comment out the rootpw option!!!

6.4. SSH configuration

If we want to be able to access a machine using SSH, we must activate the following options in the file /etc/ssh/sshd_config:

# Kerberos options
KerberosAuthentication yes
KerberosOrLocalPasswd yes
KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes

# Disable PAM authentication (make sure PasswordAuthentication is not set to no)
UsePAM no

Note

If we don't disable PAM, we will be able to access the remote machine using the Kerberos user and password, but the credentials cache won't get correctly initialized. This has a secondary effect: as long as we don't use PAM, we won't be able to automatically create the home directory for an user in her first login. On the other hand, in order to allow login to users that aren't included in Kerberos, we must activate the PasswordAuthentication option.

6.5. Logs configuration

In order to get differentiated logs for every service, we may add the following to the syslog-ng configuration file, located at /etc/syslog-ng/syslog-ng.conf:

# SASL/Kerberos/SSH/... authentication
destination auth        { file("/var/log/auth.log"); };
filter      auth        { facility(auth); };
log                     { source(src); filter(auth); destination(auth); };

# Kerberos kdc
destination krb5kdc     { file("/var/log/krb5kdc.log"); };
filter      krb5kdc     { facility(auth) and program("krb5kdc"); };
log                     { source(src); filter(krb5kdc); destination(krb5kdc); };

# Kerberos admin
destination kadmin      { file("/var/log/kadmin.log"); };
filter      kadmin      { facility(auth) and (program("kadmin.*") or program("kdb5.*")); };
log                     { source(src); filter(kadmin); destination(kadmin); };

# LDAP
destination slapd       { file("/var/log/slapd.log"); };
filter      slapd       { program("slapd"); };
log                     { source(src); filter(slapd); destination(slapd); };

Feel free to customize for your current logger.