Donnerstag, 21. Februar 2013

Mit Emacs Make dort starten, wo Makefiles liegen

Java Programmierer neigen zu exzessiv sinnlosem inflationärem Gebrauch von Unterverzeichnissen. Es gehört zum guten Ton, dass man sich erst mal durch einen Dschungel an Unterverzeichnissen hangeln muss, bevor man die erste Zeile Code schreiben darf. Sun hat es ehemals den Grundstein für diese Unart gelegt, indem man gezwungen war jedes Package in ein eigenes Verzeichnis legen zu müssen. Das entwickelte sich zum Fluch als man auf die Idee kam, sämtliche Klassennamen mit Domänennamen zu prefixen. Und die Maven-Verwirrten haben sich jetzt zum Ziel gesetzt, den Vogel endgültig abzuschießen. Man achte auf die Struktur eines simplen Hello-World-Programms:

my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

Das sind sage und schreibe 12 Verzeichnisse für 3 Dateien. Ich denke die nächste Major-Version von Maven sollte sich gemäß Moorschem Gesetz auf wenigsten 24 Verzeichnisse steigern. Getreu dem Maven-Leitspruch: Ceterum censeo inodes esse delendam.

Emacs-Benutzer, die mit dieser Anti-Information gequält werden, haben beim Entziffern der Kaiserlichen Botschaft in den Tiefen des Gesetzes das Problem, dass der Build-Vorgang nicht an der Stelle gestartet werden kann, an der die Datei liegt, die gerade editiert wird. Das zum Quellcode zugehörige Makefile oder vergleichbarer Pom-Schrott liegt typischerweise 12 bis 96 Verzeichnisse höher.

Die Lösung ist wie so oft im EmacsWiki zu finden. Dort kann man sich die Funktion upward-find-file klauen, die nach einer passenden Datei im gesamten Verzeichnisbaum sucht:

(defun upward-find-file (filename &optional startdir)
  "Move up directories until we find a certain filename. If we
  manage to find it, return the containing directory. Else if we
  get to the toplevel directory and still can't find it, return
  nil. Start at startdir or . if startdir not given"

  (let ((dirname (expand-file-name
    (if startdir startdir ".")))
 (found nil) ; found is set as a flag to leave loop if we find it
 (top nil))  ; top is set when we get
      ; to / so that we only check it once

    ; While we've neither been at the top last time nor have we found
    ; the file.
    (while (not (or found top))
      ; If we're at / set top flag.
      (if (string= (expand-file-name dirname) "/")
   (setq top t))
      
      ; Check for the file
      (if (file-exists-p (expand-file-name filename dirname))
   (setq found t)
 ; If not, move up a directory
 (setq dirname (expand-file-name ".." dirname))))
    ; return statement
    (if found (concat dirname "/") nil)))

Damit kann ein Wrapper der Compile-Funktion relativ einfach folgendermaßen definiert werden:

(defun compile-next-makefile ()
  ""
  (interactive)
  (let ((default-directory (or (upward-find-file "Makefile") ".")))
    (command-execute 'compile)))

Ich definiere mir dafür typischerweise das folgende Tastaturkürzel.

(global-set-key (kbd "C-c m") 'compile-next-makefile)

PS: Der Begriff Anti-Information ist übrigens nicht auf meinen Mist gewachsen. Den hat sich Max Landorff in "Der Regler" ausgedacht. Ich finde ihn recht passend für vieles was einem im Java-Umfeld über den Weg läuft.

Donnerstag, 14. Februar 2013

OpenLDAP Quickstart

Die Version 2.4 von OpenLDAP ist mit der Sense durch die bisherige Art das Programm zu konfigurieren gegangen. Während früher die Konfigurationsoptionen in der Datei slapd.conf lagen, liegen sie nun im Directory selber. Alle Änderungen gehen nur noch über eine LDIF-Datei, die ldapadd oder ldapmodify vorgeworfen wird. Das setzt voraus, dass der Slapd läuft. Wenn man Slapd derart verkonfiguriert, dass er nicht mehr startet, kann die fehlerhafte Konfiguration auch nicht mehr berichtigen. Es sei denn man editiert die internen cn=config-Dateien von Slapd, was man aber auf keinen Fall tun soll. Über Vor- und Nachteile dieses Ei-Huhn-Problems kann man streiten. Was aber wirklich albern ist, ist der Sachverhalt, dass die OpenLDAP-Quick-Start-Anleitung von der Konfigurationsumstellung leider noch nichts mitbekommen hat. Wenn es schnell gehen soll, ist also der alte Weg doch besser.

Wenn man der neuen reinen Lehre folgen möchte wird es komplizierter. Die folgenden Ausführungen beziehen sich auf eine Default-Installation des "openldap-servers"-Pakets eines Red Hat Enterprise Linux Servers in der Version 6.3.

Zuerst muss man die Nummer der Konfigurationsdatei finden, die Bestandteil des DN der Konfigurationsoptionen ist. Die Datei ist nämlich bereits durch die Paket-Installation angelegt worden.

# grep -l olcSuffix /etc/openldap/slapd.d/cn\=config/*
/etc/openldap/slapd.d/cn=config/cn=schema.ldif
/etc/openldap/slapd.d/cn=config/olcDatabase={2}bdb.ldif

In diesem Fall ist es '{2}bdb'. Mit Hilfe dieses Strings können nun die drei Werte gesetzt werden, die man minimaler Weise für einen Slapd setzten muss:

  • Base DN (olcSuffix)
  • Admin DN (olcRootDN)
  • Admin Passwort (olcRootPW)
Die entsprechende LDIF-Datei sieht folgendermaßen aus:

dn: olcDatabase={2}bdb,cn=config
changeType: modify
replace: olcSuffix
olcSuffix: 0=my-base

dn: olcDatabase={2}bdb,cn=config
changeType: modify
replace: olcRootDN
olcRootDN: cn=my-admin,o=my-base

dn: olcDatabase={2}bdb,cn=config
changeType: modify
replace: olcRootPW
olcRootPW: {SSHA}TAXHVcISg/XoRXTe2fSJFYpZTWYqix0t

Das Passwort erzeugt slappasswd:

# slappasswd
New password:
Re-enter new password:
{SSHA}TAXHVcISg/XoRXTe2fSJFYpZTWYqix0t

Die Datei wird mit ldapadd importiert:

# ldapadd -Y EXTERNAL -H ldapi:/// -f conf.ldif

Anschließend kann geprüft werden, ob die Anmeldung funktioniert, indem man sich mit dem Admin-Konto anmeldet:

# ldapsearch -x -D 'cn=my-admin,o=my-base' -W '(objectclass=*)'
Die Suche wird zwar kein Ergebnis liefern, weil im LDAP noch nichts enthalten ist, aber die Anmeldung mit dem neuen Passwort wird geprüft. Um sich mit JXplorer oder einem anderen Browser anzumelden, muss noch der Wurzelknoten definiert werden:
dn: o=my-base
objectclass: top
objectclass: organization
o: my-base
Der Import mit Hilfe des Manager-Kontos:
# ldapadd -x -D "cn=my-admin,o=my-base" -W -f top.ldif

Freitag, 1. Februar 2013

Netzwerkverschlüsselung für Oracle aktivieren

Oracle ist in der Lage die Netzwerkkommunikation auch ohne SSL und Zertifikate zu verschlüsseln. Dabei wird der Payload der TCP 1521-Verbindung verschlüsselt. Der Listener bekommt davon gar nichts mit und braucht auch nicht umkonfiguriert werden. Allerdings wird auf Client-Seite eine aktuelle Version des JDBC-Treibers benötigt. Das ojdbc14.jar funktioniert nicht. Man kann die Option mit dem Oracle Net Manager aktivieren:
Wichtig ist, dass der Encryption-Type auf "required" steht, da sonst auch unverschlüsselte Verbindungen zugelassen werden. Die Konfiguration steht anschließende in der sqlnet.ora-Datei:
SQLNET.ENCRYPTION_TYPES_SERVER= (AES256)
SQLNET.ENCRYPTION_SERVER = required