- Abraxas - http://www.effinger.org/blog -

Eigenes LDAP-Schema erstellen

Möchte man ein eigenes Schema erstellen, so kann man bei der IANA kostenlos ein OID anfordern [1]. Meine OID hatte ich am 17. Dezember angefordert und am 22. Dezember habe ich dann per E-Mail die Zuweisung erhalten. Man kann sich nun an die Arbeit machen und sich an der Anleitung von OpenLDAP zum Erstellen eines Schemas [2] orientieren. Für mein Projekt Mailserver mit LDAP habe ich mir die Datei dovecot.schema mit folgendem Inhalt erstellt:

# dovecot-ldap ldapv3 directory schema
#
# Based on the qmail-ldap scheme available from
# http://www.qmail-ldap.org/wiki/index.php/Qmail.schema
# Adapted for use with dovecot home mail server by Markus Effinger
# http://www.effinger.org
#
# Last change: January 11, 2009
#
# Created by: David E. Storey <dave@tamos.net>
# Modified and included into qmail-ldap by Andre Oppermann <opi@nrg4u.com>
#
# Schema fixes by Mike Jackson <mjj@pp.fi>
# Schema fixes by Christian Zoffoli (XMerlin) <czoffoli@xmerlin.org>
#
# General guideline:
# 1. The language in this file is english
# 2. Every OID in this file must look like this: ns.a.b.c.d, where
#    ns - the official namespace of the effinger schema:
#         1.3.6.1.4.1.32589
#    a  - Reserved, must always be 1 for the dovecot scheme.
#    b  - ID of object class - e.g.
#         1 = dcMailUser
#         2 = dcExternalMailAccount
#         3 = dcMailAlias
#         4 = dcPosixSubAccount
#    c  - Entry type (1:attribute, 2:object)
#    d  - Serial number (increased with every new entry)
# 3. Every entry in this file MUST have a "DESC" field, containing a
#    suitable description!
# 4. New entries are to be kept as generic as possible.
# 5. Attributes are listed in front of objects. All entries must be
#    ordered by their serial number.
#
# This schema depends on:
# - core.schema
# - cosine.schema
# - nis.schema
#
# Conflicting schema files:
# - qmail.schema
#

# Attribute Type Definitions

# dcMailUser Attributes

attributetype ( 1.3.6.1.4.1.32589.1.1.1.1
	NAME 'dcMailMessageStore'
	DESC 'Path to the maildir/mbox on the mail system'
	EQUALITY caseExactIA5Match
	SUBSTR caseIgnoreIA5SubstringsMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
	SINGLE-VALUE )

# dcExternalMailAccount Attributes

attributetype ( 1.3.6.1.4.1.32589.1.2.1.1
	NAME 'dcSubMailAddress'
	DESC 'A users secondary e-mail address for which mail from on another Mailserver has to be fetched'
	EQUALITY caseIgnoreIA5Match
	SUBSTR caseIgnoreIA5SubstringsMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.2
	NAME 'dcAccountStatus'
	DESC 'The status of a user account: active, noaccess, disabled, deleted'
	EQUALITY caseIgnoreIA5Match
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
	SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.3
	NAME 'dcSMTPServer'
	DESC 'Outgoing mails should be delivered to this Mailserver via SMTP.'
	EQUALITY caseIgnoreIA5Match
	SUBSTR caseIgnoreIA5SubstringsMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
	SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.4
	NAME 'dcSMTPLogin'
	DESC 'Login credential to send Mail with the SMTP server'
	EQUALITY caseExactIA5Match
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
	SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.5
	NAME 'dcSMTPPassword'
	DESC 'A separate text that stores the SMTP account password in clear text'
	EQUALITY caseExactIA5Match
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
	SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.6
	NAME 'dcPOP3Server'
	DESC 'Incoming mails have to be downloaded from this server via POP3.'
	EQUALITY caseIgnoreIA5Match
	SUBSTR caseIgnoreIA5SubstringsMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
	SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.7
	NAME 'dcPOP3Login'
	DESC 'Login credential to receive Mail from the POP3 server'
	EQUALITY caseExactIA5Match
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
	SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.8
	NAME 'dcPOP3Password'
	DESC 'A separate text that stores the POP3 account password in clear text'
	EQUALITY caseExactIA5Match
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
	SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.9
	NAME 'dcMailQuota'
	DESC 'The size of space the user can have until further messages get bounced.'
	EQUALITY integerMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
	SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.32589.1.2.1.10
	NAME 'dcMailSizeMax'
	DESC 'The maximum size of a single messages the user accepts.'
	EQUALITY integerMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
	SINGLE-VALUE )

# dcMailAlias Attributes

attributetype ( 1.3.6.1.4.1.32589.1.3.1.1
	NAME 'dcMailAlternateAddress'
	DESC 'Secondary (alias) mailaddresses for the same user'
	EQUALITY caseIgnoreIA5Match
	SUBSTR caseIgnoreIA5SubstringsMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

attributetype ( 1.3.6.1.4.1.32589.1.3.1.2
	NAME 'dcMailForwardingAddress'
	DESC 'Any mails addressed to aliases should be forwarded to this mail address'
	EQUALITY caseIgnoreIA5Match
	SUBSTR caseIgnoreIA5SubstringsMatch
	SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

# dcPosixSubAccount Attributes

# We want another attribute pointing to the respective posixOwner with an LDAP URL
attributetype ( 1.3.6.1.4.1.32589.1.4.1.1
	NAME 'dcPosixOwnerURL'
	DESC 'Identifies an URL associated with the posixOwner of the entry. Any type of labeled URL can be used.'
	SUP labeledURI )

# Object Class Definitions

objectclass ( 1.3.6.1.4.1.32589.1.1.2.1
	NAME 'dcMailUser'
	DESC 'Dovecot-LDAP User'
	SUP top
	AUXILIARY
	MUST ( dcMailMessageStore ) )

objectclass ( 1.3.6.1.4.1.32589.1.2.2.1
	NAME 'dcExternalMailAccount'
	DESC 'Dovecot-LDAP external mail account'
	SUP top
	STRUCTURAL
	MUST ( dcSubMailAddress $ dcAccountStatus)
	MAY (
		dcSMTPServer $ dcSMTPLogin $ dcSMTPPassword $
		dcPOP3Server $ dcPOP3Login $ dcPOP3Password $
		dcMailQuota $ dcMailSizeMax ) )

objectclass ( 1.3.6.1.4.1.32589.1.3.2.1
	NAME 'dcMailAlias'
	DESC 'Dovecot Mail Alias'
	SUP top
	STRUCTURAL
	MUST ( dcMailAlternateAddress )
	MAY ( dcMailForwardingAddress ) )

# ObjectClass used for dynamically retrieving the posixOwner
objectClass ( 1.3.6.1.4.1.32589.1.4.2.1
	NAME 'dcPosixSubAccount'
	DESC 'LDAP-URL for retrieving the respective posixAccount of an entry'
	SUP top
	AUXILIARY
	MAY ( dcPosixOwnerURL ) )

Wenn man eine Schema-Datei erstellt hat, kann man diese jedoch mit der aktuellen OpenLDAP-Version nicht unmittelbar benutzen, weil diese das cn=config Schema verwendet. Man muss aus diesem Grund erst einmal das Schema in eine entsprechende LDIF-Datei umwandeln. Dazu kopiert man als root zunächst das gesamte LDAP-Konfigurationsverzeichnis an einen temporären Ort (z.B. ~/tmp/test.d) mit

sudo cp -R /etc/ldap/slapd.d ~/tmp/test.d

Anschließend erstellt man sich eine Fake slapd.conf beispielsweise mit folgendem Inhalt:

database config
rootdn "cn=admin,cn=config"

include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /path/to/dovecot.schema

Wichtig dabei ist, dass man auf die zu konvertierende Schema-Datei verweist. Mit einem

sudo slaptest -f path/to/slapd.conf -F /tmp/test.d/

kann man nun die Konvertierung starten. Die Ausgabe erfolgt im Ordner /tmp/test.d/cn=config/cn=schema/. Dort sollte sich nun eine entsprechende Datei (hier cn={4}dovecot.ldif) befinden.
Diese Datei editiert man und entfernt die Durchnummerierungmit {x}, die unnötigen Zeilenumbrüche und die sieben letzten Zeilen. Außerdem korrigiert man noch den Wert von dn in der ersten Zeile. Aus

dn: cn={4}dovecot
objectClass: olcSchemaConfig
cn: {4}dovecot
olcAttributeTypes: {0}( 1.3.6.1.4.1.32589.1.1.1.1 NAME 'dcMailMessageStore' DE
 SC 'Path to the maildir/mbox on the mail system' EQUALITY caseExactIA5Match S
 UBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
 SINGLE-VALUE )
olcAttributeTypes: {1}( 1.3.6.1.4.1.32589.1.2.1.1 NAME 'dcSubMailAddress' DESC
  'A users secondary e-mail address for which mail from on another Mailserver
 has to be fetched' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5Substrings
 Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
olcAttributeTypes: {2}( 1.3.6.1.4.1.32589.1.2.1.2 NAME 'dcAccountStatus' DESC
 'The status of a user account: active, noaccess, disabled, deleted' EQUALITY
 caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: {3}( 1.3.6.1.4.1.32589.1.2.1.3 NAME 'dcSMTPServer' DESC 'Ou
 tgoing mails should be delivered to this Mailserver via SMTP.' EQUALITY caseI
 gnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115
 .121.1.26{256} SINGLE-VALUE )
olcAttributeTypes: {4}( 1.3.6.1.4.1.32589.1.2.1.4 NAME 'dcSMTPLogin' DESC 'Log
 in credential to send Mail with the SMTP server' EQUALITY caseExactIA5Match S
 YNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: {5}( 1.3.6.1.4.1.32589.1.2.1.5 NAME 'dcSMTPPassword' DESC '
 A separate text that stores the SMTP account password in clear text' EQUALITY
  caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: {6}( 1.3.6.1.4.1.32589.1.2.1.6 NAME 'dcPOP3Server' DESC 'In
 coming mails have to be downloaded from this server via POP3.' EQUALITY caseI
 gnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115
 .121.1.26{256} SINGLE-VALUE )
olcAttributeTypes: {7}( 1.3.6.1.4.1.32589.1.2.1.7 NAME 'dcPOP3Login' DESC 'Log
 in credential to receive Mail from the POP3 server' EQUALITY caseExactIA5Matc
 h SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: {8}( 1.3.6.1.4.1.32589.1.2.1.8 NAME 'dcPOP3Password' DESC '
 A separate text that stores the POP3 account password in clear text' EQUALITY
  caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: {9}( 1.3.6.1.4.1.32589.1.2.1.9 NAME 'dcMailQuota' DESC 'The
  size of space the user can have until further messages get bounced.' EQUALIT
 Y integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcAttributeTypes: {10}( 1.3.6.1.4.1.32589.1.2.1.10 NAME 'dcMailSizeMax' DESC
 'The maximum size of a single messages the user accepts.' EQUALITY integerMat
 ch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcAttributeTypes: {11}( 1.3.6.1.4.1.32589.1.3.1.1 NAME 'dcMailAlternateAddres
 s' DESC 'Secondary (alias) mailaddresses for the same user' EQUALITY caseIgno
 reIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.12
 1.1.26{256} )
olcAttributeTypes: {12}( 1.3.6.1.4.1.32589.1.3.1.2 NAME 'dcMailForwardingAddre
 ss' DESC 'Any mails addressed to aliases should be forwarded to this mail add
 ress' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX
 1.3.6.1.4.1.1466.115.121.1.26{256} )
olcAttributeTypes: {13}( 1.3.6.1.4.1.32589.1.4.1.1 NAME 'dcPosixOwnerURL' DESC
  'Identifies an URL associated with the posixOwner of the entry. Any type of
 labeled URL can be used.' SUP labeledURI )
olcObjectClasses: {0}( 1.3.6.1.4.1.32589.1.1.2.1 NAME 'dcMailUser' DESC 'Dovec
 ot-LDAP User' SUP top AUXILIARY MUST dcMailMessageStore )
olcObjectClasses: {1}( 1.3.6.1.4.1.32589.1.2.2.1 NAME 'dcExternalMailAccount'
 DESC 'Dovecot-LDAP external mail account' SUP top STRUCTURAL MUST ( dcSubMail
 Address $ dcAccountStatus ) MAY ( dcSMTPServer $ dcSMTPLogin $ dcSMTPPassword
  $ dcPOP3Server $ dcPOP3Login $ dcPOP3Password $ dcMailQuota $ dcMailSizeMax
 ) )
olcObjectClasses: {2}( 1.3.6.1.4.1.32589.1.3.2.1 NAME 'dcMailAlias' DESC 'Dove
 cot Mail Alias' SUP top STRUCTURAL MUST dcMailAlternateAddress MAY dcMailForw
 ardingAddress )
olcObjectClasses: {3}( 1.3.6.1.4.1.32589.1.4.2.1 NAME 'dcPosixSubAccount' DESC
  'LDAP-URL for retrieving the respective posixAccount of an entry' SUP top AU
 XILIARY MAY dcPosixOwnerURL )
structuralObjectClass: olcSchemaConfig
entryUUID: 404fb912-7462-102d-9516-f3eb0dd72c8a
creatorsName: cn=config
createTimestamp: 20090111193156Z
entryCSN: 20090111193156.153615Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20090111193156Z

wird so die fertige dovecot.schema.ldif

dn: cn=dovecot,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: dovecot
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.1.1.1 NAME 'dcMailMessageStore' DESC 'Path to the maildir/mbox on the mail system' EQUALITY caseExactIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.1 NAME 'dcSubMailAddress' DESC 'A users secondary e-mail address for which mail from on another Mailserver has to be fetched' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.2 NAME 'dcAccountStatus' DESC 'The status of a user account: active, noaccess, disabled, deleted' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.3 NAME 'dcSMTPServer' DESC 'Outgoing mails should be delivered to this Mailserver via SMTP.' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.4 NAME 'dcSMTPLogin' DESC 'Login credential to send Mail with the SMTP server' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.5 NAME 'dcSMTPPassword' DESC 'A separate text that stores the SMTP account password in clear text' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.6 NAME 'dcPOP3Server' DESC 'Incoming mails have to be downloaded from this server via POP3.' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.7 NAME 'dcPOP3Login' DESC 'Login credential to receive Mail from the POP3 server' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.8 NAME 'dcPOP3Password' DESC 'A separate text that stores the POP3 account password in clear text' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.9 NAME 'dcMailQuota' DESC 'The size of space the user can have until further messages get bounced.' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.2.1.10 NAME 'dcMailSizeMax' DESC 'The maximum size of a single messages the user accepts.' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.3.1.1 NAME 'dcMailAlternateAddress' DESC 'Secondary (alias) mailaddresses for the same user' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.3.1.2 NAME 'dcMailForwardingAddress' DESC 'Any mails addressed to aliases should be forwarded to this mail address' EQUALITY caseIgnoreIA5Match SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
olcAttributeTypes: ( 1.3.6.1.4.1.32589.1.4.1.1 NAME 'dcPosixOwnerURL' DESC 'Identifies an URL associated with the posixOwner of the entry. Any type of labeled URL can be used.' SUP labeledURI )
olcObjectClasses: ( 1.3.6.1.4.1.32589.1.1.2.1 NAME 'dcMailUser' DESC 'Dovecot-LDAP User' SUP top AUXILIARY MUST dcMailMessageStore )
olcObjectClasses: ( 1.3.6.1.4.1.32589.1.2.2.1 NAME 'dcExternalMailAccount' DESC 'Dovecot-LDAP external mail account' SUP top STRUCTURAL MUST ( dcSubMailAddress $ dcAccountStatus ) MAY ( dcSMTPServer $ dcSMTPLogin $ dcSMTPPassword $ dcPOP3Server $ dcPOP3Login $ dcPOP3Password $ dcMailQuota $ dcMailSizeMax ) )
olcObjectClasses: ( 1.3.6.1.4.1.32589.1.3.2.1 NAME 'dcMailAlias' DESC 'Dovecot Mail Alias' SUP top STRUCTURAL MUST dcMailAlternateAddress MAY dcMailForwardingAddress )
olcObjectClasses: ( 1.3.6.1.4.1.32589.1.4.2.1 NAME 'dcPosixSubAccount' DESC 'LDAP-URL for retrieving the respective posixAccount of an entry' SUP top AUXILIARY MAY dcPosixOwnerURL )