Kategorien

Eigenes LDAP-Schema erstellen

Möchte man ein eigenes Schema erstellen, so kann man bei der IANA kostenlos ein OID anfordern. 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 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 )

Aktuelles RubyRipper unter Ubuntu

Da ich meine CDs als eine FLAC-Datei mit einem entsprechendem CUE-Sheet auf meinen Rechner speichern möchte, bin ich auf einen Bug in RubyRipper gestoßen:

Wrong filesize reported for track 0 : 500249276
Filesize should be : 54502940
/usr/local/rubyripper/lib/site_ruby/1.8/rr_lib.rb:933:in `delete': No such file or directory

Wie man im Bugreport nachlesen kann, vergleicht RubyRipper fälschlicherweise die Größe des ersten Tracks mit der Gesamt-CD. Dieser Bug wurde in der Repository-Version behoben. Grund genug für mich, die aktuellste Version aus den Repositories zu installieren. Zunächst müssen dazu git und die anderen abhängigen Pakete installiert werden (siehe anderer Beitrag), damit wir die Version aus dem Repository verwenden können:

sudo apt-get install git-core cd-discid cdparanoia ruby ruby-pkg-tools libgettext-ruby1.8 libgtk2-ruby

Dann werden die aktuellsten Dateien aus dem Repository heruntergeladen – beim ersten Mal mit

git clone git://github.com/rubyripperdev/rubyripper.git

falls wir irgendwann später aktualisieren wollen stattdessen mit

cd rubyripper
git pull

Anschließend wird im Unterverzeichnis rubyripper das Konfigurationsprogramm gestartet:

./configure --enable-lang-all --enable-gtk2 --enable-cli --prefix=/usr/local/rubyripper

Mit einem

sudo make install

wird Rubyripper in das Verzeichnis /usr/local/rubyripper installiert, von wo aus es abschließend sehr einfach mit stow installiert werden kann.

Das kleine OpenLDAP 1×1

Um meine Mailserverkonfiguration auf LDAP umzustellen, musste ich mich mit OpenLDAP beschäftigen. Da OpenLDAP seit Version 2.3 (aktuell ist 2.4) die von der vormaligen Konfigurationsdatei slapd.conf umgestellt hat auf ein LDAP-basiertes Schema, nämlich cn=config, kann man mit vielen Anleitungen und Tutorials nicht mehr wirklich etwas anfangen, da sich Vieles geändert hat. Die folgenden Punkte sollen helfen, trotzdem mit OpenLDAP einigermaßen umgehen zu können. Wenn man jedoch kompletter LDAP-Neuling ist, empfehle ich unbedingt, sich vorher die LDAP Grundlagen (sehr gute Einführung von Stefan Kania) anzueignen. Noch ein kleiner Hinweis alle folgenden Befehle (bis auf diejenigen mit ldapadd) sind als root auszuführen, also am Besten nach einen

sudo bash

oder einem

sudo -s

weiter arbeiten.

Einrichtung unter Ubuntu

Bei der Installation von OpenLDAP mit

apt-get install slapd ldap-utils

kann man schon grundlegende Dinge festlegen (unbedingt das Administrator Passwort merken). Mit einem

dpkg-reconfigure slapd

kann man auch weitergehende Einstellungen vornehmen, allerdings haben mir einige Dinge dabei nicht gefallen:

  • Die Einrichtung einer Datenbank wird auf Basis eines Domainnamens (z.B. dc=effinger,dc=org) vorgenommen
  • Der entsprechende Eintrag für einen Administrator dieses DNs (dc=effinger,dc=org) wird nicht geschrieben, was bedeutet, dass man standardmäßig keine Einträge schreiben kann, sondern erst von Hand in cn=config den entsprechenden RootDN anlegen muss

Aus diesem Grund empfehle ich, die Konfiguration selbst vorzunehmen.

Erzeugte Datenbanken löschen

Eine erstellte Datenbank zu löschen ist gar nicht so einfach. Ich hatte zuerst gedacht es wäre möglich einfach den entsprechenden DN in cn=config zu entfernen (also beispielsweise cn=config,olcDatabase={1}hdb löschen), aber das funktioniert nicht. Stattdessen muss man mit

/etc/init.d/slapd stop

zunächst den OpenLDAP Server stoppen, um dann im Verzeichnis /etc/ldap/slapd.d/cn=config die entsprechende Datei (hier olcDatabase={1}hdb) nach dem Speicherort der Datenbank zu durchforsten:

cat /etc/ldap/slapd.d/cn\=config/olcDatabase\=\{1\}hdb.ldif | grep olcDbDirectory

Durch die Ausgabe (z.B. „olcDbDirectory: /var/lib/ldap“) weiß man nun den Pfad der Datenbank (hier /var/lib/ldap), den man nun zusammen mit der entsprechenden Konfigurationsdatei löscht:

rm /etc/ldap/slapd.d/cn\=config/olcDatabase\=\{1\}hdb.ldif && rm /var/lib/ldap/*

Im Anschluss starten wir den OpenLDAP Server wieder:

/etc/init.d/slapd start

Neue Datenbank erzeugen

Um eine neue Datenbank zu erzeugen, habe ich mir die Vorlage unter /usr/share/slapd/slapd.init.ldif zum Vorbild genommen (siehe auch OpenLDAP Admin Guide) und angepasst. Herausgekommen ist dabei meine database.ldif:

# Database settings
dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: hdb
# The base of your directory
olcSuffix: o=effinger
# rootdn directive for specifying a superuser on the database. This is needed
# for syncrepl.
olcRootDN: cn=admin,o=effinger
# Superuser Password for the database
# {SSHA}pEvotN6PmSjx0JV/mZl5BWeSVOKR1Ejt equals "test"
# CHANGE this for your installation!!!
olcRootPW: {SSHA}pEvotN6PmSjx0JV/mZl5BWeSVOKR1Ejt
# Where the database file are physically stored
olcDbDirectory: /var/lib/ldap
# The dbconfig settings are used to generate a DB_CONFIG file the first
# time slapd starts.  They do NOT override existing an existing DB_CONFIG
# file.  You should therefore change these settings in DB_CONFIG directly
# or remove DB_CONFIG and restart slapd for changes to take effect.
# For the Debian package we use 2MB as default but be sure to update this
# value if you have plenty of RAM

olcDbConfig: set_cachesize 0 2097152 0
# Sven Hartge reported that he had to set this value incredibly high
# to get slapd running at all. See http://bugs.debian.org/303057 for more
# information.
# Number of objects that can be locked at the same time.
olcDbConfig: set_lk_max_objects 1500
# Number of locks (both requested and granted)
olcDbConfig: set_lk_max_locks 1500
# Number of lockers
olcDbConfig: set_lk_max_lockers 1500
# Indexing options
olcDbIndex: objectClass eq
# Save the time that the entry gets modified
olcLastMod: TRUE
# Checkpoint the BerkeleyDB database periodically in case of system
# failure and to speed slapd shutdown.
olcDbCheckpoint: 512 30
# The userPassword by default can be changed
# by the entry owning it if they are authenticated.
# Others should not be able to see it, except the
# admin entry below
# These access lines apply to database #1 only
olcAccess: to attrs=userPassword,shadowLastChange by dn="cn=admin,o=effinger" write by anonymous auth by self write by * none
# Ensure read access to the base for things like
# supportedSASLMechanisms.  Without this you may
# have problems with SASL not knowing what
# mechanisms are available and the like.
# Note that this is covered by the 'access to *'
# ACL below too but if you change that as people
# are wont to do you'll still need this if you
# want SASL (and possible other things) to work
# happily.
olcAccess: to dn.base="" by * read
# The admin dn has full write access, everyone else
# can read everything.
olcAccess: to * by dn="cn=admin,o=effinger" write by * read
# For Netscape Roaming support, each user gets a roaming
# profile for which they have write access to
#olcAccess: to dn=".*,ou=Roaming,o=morsnet" by dn="cn=admin,o=effinger" write by dnattr=owner write

Bitte unbedingt das Passwort (olcRootPW) ändern. Den entsprechenden String erhält man durch Ausführen von slappasswd. Dann kann man durch ein

ldapadd -f database.ldif -x -D "cn=admin,cn=config" -W

die entsprechende Datenbank erzeugen, wobei man nach dem Passwort gefragt wird, das man bei der Installation von slapd angegeben hat (also nicht das soeben mit slappasswd erzeugte). Was jetzt noch fehlt, sind entsprechende Einträge in der Datenbank. Dazu erzeugen wir eine neue Datei namens database-content.ldif mit diesem Inhalt:

dn: o=effinger
objectclass: organization
objectclass: top
o: effinger

Die wir analog an OpenLDAP mit

ldapadd -f database-content.ldif -x -D "cn=admin,o=effinger" -W

übergeben. Hierbei muss das Passwort eingegeben werden, das oben mit slappasswd erzeugt wurde.

Schema-Dateien mit cn=config

Um die weit verbreiteten Schema-Dateien in das neue Konfigurationsschema cn=config von OpenLDAP zu übernehmen, habe ich in eine Anleitung in der Ubuntu-Server Guide gefunden. Bei Gelegenheit werde ich diese mal ausprobieren und meine Erfahrungen dazu schildern.

Die nächsten Schritte mit LDAP

Jetzt kann man loslegen und mit den ldap-utils weiter an dem Verzeichnis arbeiten oder noch besser, man verwendet dazu grafische Programme wie JXplorer oder LDAP Browser/Editor, zwei wirklich empfehlenswerte, Java-basierte Tools. Um sie zu benutzen habe ich mit einem

apt-get install sun-java6-jre

das Sun Java Runtime Environment installiert. Das Shell-Skript jxplorer.sh von JXplorer musste ich noch leicht anpassen, da ich folgenden Fehler beim starten erhielt: Unrecognized option: -Xdock:name=JXplorer Could not create the Java virtual machine. Die Anpassungen hier als diff:

--- jxplorer.sh.old	2008-09-07 01:28:40.000000000 +0200
+++ jxplorer.sh	2008-12-13 14:56:51.402593159 +0100
@@ -38,14 +38,14 @@
 echo
 FAIL=0
 if [ "$1" = "console" ] ; then
-    $JAVAV -Xdock:name="JXplorer" -Dcom.apple.macos.useScreenMenuBar=true -cp .:jars/jxplorer.jar:jars/help.jar:jars/jhall.jar:jars/junit.jar:jars/ldapsec.jar:jars/log4j.jar:jars/dsml/activation.jar:jars/dsml/commons-logging.jar:jars/dsml/dom4j.jar:jars/dsml/jxext.jar:jars/dsml/mail.jar:jars/dsml/providerutil.jar:jars/dsml/saaj-api.jar:jars/dsml/saaj-ri.jar com.ca.directory.jxplorer.JXplorer
+    $JAVAV -cp .:jars/jxplorer.jar:jars/help.jar:jars/jhall.jar:jars/junit.jar:jars/ldapsec.jar:jars/log4j.jar:jars/dsml/activation.jar:jars/dsml/commons-logging.jar:jars/dsml/dom4j.jar:jars/dsml/jxext.jar:jars/dsml/mail.jar:jars/dsml/providerutil.jar:jars/dsml/saaj-api.jar:jars/dsml/saaj-ri.jar com.ca.directory.jxplorer.JXplorer

     if [ "$?" != "0" ]; then
         FAIL=1
     fi
 else
     echo "Use \"jxstart.sh console\" if you want logging to the console"
-    $JAVAV -Xdock:name="JXplorer" -Dcom.apple.macos.useScreenMenuBar=true -cp .:jars/jxplorer.jar:jars/help.jar:jars/jhall.jar:jars/junit.jar:jars/ldapsec.jar:jars/log4j.jar:jars/dsml/activation.jar:jars/dsml/commons-logging.jar:jars/dsml/dom4j.jar:jars/dsml/jxext.jar:jars/dsml/mail.jar:jars/dsml/providerutil.jar:jars/dsml/saaj-api.jar:jars/dsml/saaj-ri.jar com.ca.directory.jxplorer.JXplorer  >/dev/null 2>&1
+    $JAVAV -cp .:jars/jxplorer.jar:jars/help.jar:jars/jhall.jar:jars/junit.jar:jars/ldapsec.jar:jars/log4j.jar:jars/dsml/activation.jar:jars/dsml/commons-logging.jar:jars/dsml/dom4j.jar:jars/dsml/jxext.jar:jars/dsml/mail.jar:jars/dsml/providerutil.jar:jars/dsml/saaj-api.jar:jars/dsml/saaj-ri.jar com.ca.directory.jxplorer.JXplorer  >/dev/null 2>&1

     if [ "$?" != "0" ]; then
         FAIL=1

Um die Änderungen vorzunehmen einfach den obigen Inhalt als patch.diff im selben Verzeichnis wie die jxplorer.sh speichern und dann ein

patch -p0 < patch.diff

ausführen.

Happy LDAPing!

Pulseaudio unter Intrepid Ibex bändigen?

Die Überschrift deutet es mit dem Wort bändigen schon an: Pulseaudio ist nicht gerade gut in Ubuntu integriert worden (siehe auch die entsprechende Pulseaudio-Howto). Vor allem an der Stabilität mangelt es auf meinem Rechner. Dann hängt mein Banshee, die Lautsprecher bleiben stumm und in der Syslog ist Folgendes zu lesen:

pulseaudio[27844]: protocol-native.c: Failed to push data into queue
last message repeated 11451 times

Wenn ich nun pulseaudio beenden möchte mit einem

pulseaudio --kill

bekomme ich nur ein

W: ltdl-bind-now.c: Failed to find original dlopen loader.

Es über ein

pkill /usr/bin/pulseaudio

zu beenden klappt auch nicht, da muss schon ein

pkill -9 /usr/bin/pulseaudio

ran, um dieses widerspenstige Ding zu bändigen. Danach lässt es sich wenigstens über Alt+F2 und die Eingabe von /usr/bin/pulseaudio starten und gibt wieder Laute von sich. Wenn jemand eine dauerhafte Lösung für dieses Problem gefunden hat (Pulseaudio hängt sich bei mir ca. alle 1-3 Tage auf), wäre ich für das Posten der Lösung sehr dankbar, denn auch das Befolgen der Anweisungen der oben erwähnten Pulseaudio-Howto haben mich nicht weitergebracht.

Probleme mit Compiz – fehlende Fensterrahmen

Compiz zu benutzen macht zwar Spaß und gibt optisch einiges mehr her, aber so wirklich ausgereift ist es noch nicht. Bei mir traten folgende Probleme auf, die ich mittlerweile aber lösen konnte:

  1. Alle Fenster ohne Fensterrahmen
  2. Firefox ohne Fensterrahmen

Mit Erschrecken musste ich unter Intrepid Ibex feststellen, dass alle Fensterrahmen verschwunden waren – kein Schließen, Maximieren oder Minimieren mehr noch das Verschieben auf eine andere Arbeitsfläche war (über die Maus) möglich. Das Ganze liegt wohl an einem Bug im Ubuntu-Standardtheme im Zusammenspiel mit NVidia-Treibern. Einen Workaround habe ich schließlich bei Suzan gefunden: Man muss ein bugfreies Fensterrahmentheme installieren und aktivieren, beispielsweise EnergyOrange. Dazu öffnet man unter System>Einstellungen>Erscheinungsbild den Reiter Thema. In dieses Fenster zieht man die heruntergeladene Theme-Datei. Anschließend wählt man das Human-Theme aus und geht auf Anpassen>Fensterrahmen. Dort wählt man nun das besagte EnergyOrange-Theme aus und die Fensterrahmen sollten nun dauerhaft erhalten bleiben.

So nun zum zweiten Problem, den verschwindenden Fensterrahmen bei Firefox, die auch nach der oben beschriebenen Änderung auftreten können. Das ist ein Bug, dessen Auftreten man durch das Abstellen einer Compiz-Einstellung unterbinden kann. Den Compiz-Einstellungsmanager starten (entweder über Alt-F2 und ccsm oder über System>Einstellungen>CompizConfig), dann unter Werkzeuge>Abhilfen das Häkchen bei Legacy Fullscreen Support entfernen. Jetzt funktioniert es hoffentlich wieder – falls nicht, hilft es meist über F11 in den Vollbildmodus zu wechseln und dann über F11 wieder in den normalen Modus zurückzukehren.