Kategorien

Eigenes PPA-Repository auf Launchpad einrichten

Ein Launchpad-Repository (PPA – personal package archive) mit 1 GB freiem Speicherplatz hilft den eigenen Webserver zu entlasten. Der ersten Schritt zum eigenen Repository ist die Anmeldung bei Launchpad.

Erzeugen eines OpenPGP-Schlüssels

Um ein Repository zu bekommen, benötigt man außerdem einen OpenPGP Schlüssel. Diesen habe ich mit dem Befehl

gpg --gen-key

erzeugt. Dabei habe ich für Art, Gültigkeit und Schlüssellänge stets die vorgegebenen Standardwerte verwendet. Bei den persönlichen Angaben bitte keinen Kommentar eingeben. Zum Schluss erhält man auch eine Zeile mit der Ausgabe

pub   1024D/8E7FE678 2009-01-21

Die öffentliche Schlüssel-ID beträgt hier also 8E7FE678. Diese Ausgabe erhält man im Nachhinein übrigens mit einem

gpg --list-keys

für alle erzeugten Schlüssel bzw. für eine spezielle E-Mail-Addresse mit

gpg --list-keys your@mailaddress.com

Damit die öffentliche Schlüssel-ID allen Programmen zur Verfügung steht, setzen wir die entsprechende Umgebungsvariable durch Ergänzung der .bashrc um folgende Zeile (Schlüssel-ID anpassen):

export GPGKEY=8E7FE678

Außerdem sollte man sicherstellen, dass die Angaben zu den Packages, die aus den zwei Umgebungsvariablen DEBFULLNAME und DEBEMAIL gelesen werden, vorhanden sind. Die Schreibweise muss exakt mit den gemachten Angaben zur Erzeugung des OpenPGP-Schlüssels übereinstimmen:

export DEBFULLNAME='Your Name'
export DEBEMAIL='your@mailaddress.org'

Gibt es Differenzen erhält man nämlich bei der Erstellung von Paketen folgende Fehlermeldung: „geheimer schlüssel ist nicht vorhanden“ bzw. „secret key not available“. Als nächstes Übertragen wir den öffentlichen Schlüssel auf einen öffentlichen Schlüsselserver

gpg --send-keys --keyserver keyserver.ubuntu.com 8E7FE678

Die Schlüssel-ID ist hier natürlich ebenfalls anzupassen.

Aktivieren des Launchpad-Repositories

Zum Aktivieren des Launchpad-Repositories meldet man sich mit seinem Login an und klickt auf seinen Namen (rechts oben), so dass man zum eigenen Profil komt. Anschließend wählt dann den Punkt Change Details. Im Menü wählt man OpenPGP Keys und gibt dort die Finger-Print des Schlüssels ein, den man über ein

gpg --fingerprint 8E7FE678

erhält (wiederum für eigene Schlüssel-ID anpassen). Nach dem Importieren erhält man eine E-Mail, deren Inhalt einen verschlüsselten Link enthält, den man zum Aktivieren aufrufen muss. Zum Entschlüsseln wird der entsprechende Inhalt (ab einschließlich —–BEGIN PGP MESSAGE—– bis —–END PGP MESSAGE—–) in der Datei temp.txt gespeichert, die man dann durch ein

gpg --decrypt temp.txt

in den Klartext verwandelt. Durch Aufrufen des enthaltenen Links bestätigt man den Schlüssel nochmals und kann dann unter seinem Profil das PPA aktivieren. Im nächsten Schritt muss man Ubuntero werden, d.h. den Ubuntu Verhaltenskodex akzeptieren. Ist man dies nicht, werden hochgeladene Pakete mit der Fehlermeldung „PPA uploads must be signed by an ‚ubuntero‘. “ verworfen. Um Ubuntero zu werden ruft man nach dem Einloggen die Seite Ubuntu Code of Conduct auf, geht auf den Punkt Sign it!, lädt den Kodex herunter und signiert ihn mit einem

gpg --clearsign UbuntuCodeofConduct-1.0.1.txt

Den Inhalt der dadurch erzeugten Datei UbuntuCodeofConduct-1.0.1.txt.asc fügt man nun in das entsprechende Feld ein, schickt das Formular ab – und schon ist man Ubuntero.

Pakete erstellen und ins Repository übernehmen

Eigene Pakete muss man fortan beim Erstellen signieren, falls sie in das PPA-Repository aufgenommen werden sollen. Falls man ein bereits im Ubuntu-Repository vorhandenes Paket angepasst hat, also die Datei names xyz.orig.tar.gz von Beginn an vorhanden ist, so erstellt man mit

debuild -S -sd

die entsprechenden Dateien – ansonsten mit

debuild -S -sa

Zum Hochladen installiert man dput mit

sudo apt-get install dput

und erzeugt die Datei ~/.dput.cf mit diesem Inhalt (bitte launchpad-id anpassen):

[my-ppa]
fqdn = ppa.launchpad.net
method = ftp
incoming = ~your-launchpad-id/ubuntu/
login = anonymous
allow_unsigned_uploads = 0

Das erzeugte Source-Paket wird schließlich durch ein

dput my-ppa P_V_source.changes

ins Repository übertragen. P steht dabei für den Paketnamen und V für die Versionsnummer. Die Datei P_V_source.changes sollte sich natürlich im entsprechenden Verzeichnis befinden. Anfangs habe ich mich gefragt, weshalb man zum Hochladen kein Passwort oder dergleichen benötigt, aber da die erzeugten Pakete signiert sind, ist das ja gar nicht notwendig.
Die hochgeladenen Quelltext-Pakete werden dann von Launchpad für die Platformen i386, AMD64 und LPIA kompiliert und  anschließend ins Repository gestellt. Das kann etwas dauern. Natürlich sollte man vorher selbst sicherstellen, dass das Kompilieren auf dem eigenen Rechner fehlerfrei abläuft. Während in der Vergangenheit die Packages auf dem Launchpad PPA nicht signiert wurden, soll dies zukünftig anders sein. Ich bin gespannt, wann meine Pakete signiert sind..

Kleine Tips zum Schluss

GPG-Agent nutzen

Der gpg-agent erlaubt eine etwas bequemere Anwendung von GPG, da bei mehrfacher Verwendung eines Schlüssels innerhalb einer bestimmten Zeitspanne nur beim ersten Mal nach dem Passwort gefragt wird. Installieren lässt sich der gpg-agent mit einem

sudo apt-get install gnupg-agent

Damit der gpg-agent bei jeder Sitzung gestartet wird, habe ich ihn unter System>Einstellungen>Sitzungen als Startprogramm mit dem Befehl

gpg-agent --daemon

hinzugefügt.

Schlüssel zurückziehen

Hat jemand Zugang zum privaten Schlüssel erhalten, so kann man den Schlüssel zurückziehen/als ungültig markieren (revoke). Die sehr gute revoke-Anleitung von Hackdiary hilft dabei. Lediglich den dort angegebenen MIT Server habe ich durch den Ubuntu Server ersetzt, an den ich meinen öffentlichen Schlüssel gesendet hatte. Das sollte eigentlich aber keinen Unterschied machen, da die Schlüsselserver die öffentlichen Schlüssel untereinander austauschen.

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.