vsftpd setup – the missing information

So I set up vsftpd on my Debian box the other day. I wanted a simple virtual users setup, so I created /etc/vsftpd, moved and symlinked my vsftpd.conf into this directory (to keep Debian happy) and also added a /etc/vsftpd/users.txt file – the source for my db(1) database that pam should use, after I compiled it with

$ cd /etc/vsftpd && db4.6_load -T -t hash -f users.txt users.db

Now that the database existed I went to /etc/pam.d/vsftpd and configured it there

session optional    pam_keyinit.so force revoke
auth    required    /lib/security/pam_userdb.so \
account required    /lib/security/pam_userdb.so \

but when I tried to log in, vsftpd always reported 530: Login incorrect (and of course I specified an existing user with a correct password). So what went wrong?

After struggling with it for quite some time I noticed that my /var/log/auth.log contained output from pam:

vsftpd: pam_userdb(vsftpd:auth): Verify user `foo' with a password
vsftpd: pam_userdb(vsftpd:auth): user_lookup: could not open database `/etc/vsftpd/users.db': No such file or directory

Huh?! Of course /etc/vsftpd/users.db exists – though it is only read-/writable by root (600), this shouldn’t matter much, because vsftpd runs as root anyways.

Well, the nice thing about the internet is that there is usually at least one person who already had the same problem like you and eventually solved it – and that was the case here as well:

It turned out that pam_userdb.so silently appends .db to the given path, so all I had to do to make it work was stripping off my .db in /etc/pam.d/vsftpd:

session optional    pam_keyinit.so force revoke
auth    required    /lib/security/pam_userdb.so \
account required    /lib/security/pam_userdb.so \

If you look into pam_userdb(8) you won’t find any hint about that – even worse, the example in the man page uses the explicit .db suffix as well (at least here on Lenny).

Anyways, I have now an easy-to-manage ftp server and one reason less to trust anyhow into DropBox and friends ­čÖé

Einf├╝hrung die Versionsverwaltung mit monotone

Mathias Weidner hat eine deutschsprachige Einf├╝hrung in die Versionverwaltung mit monotone ver├Âffentlicht. Er behandelt darin die Grundlagen der verteilten Versionsverwaltung, die ersten Schritte mit monotone, sowie die t├Ąglich anfallende Arbeitspraxis mit einem Versionskontrollsystem. In sp├Ąteren Kapiteln widmet sich Mathias auch erweiterten Themen, etwa wie monotone auf die individuellen Bed├╝rfnisse des Nutzers angepasst werden kann und liefert weitere n├╝tzliche Hinweise f├╝r Ein- und Umsteiger von anderen Versionskontrollsystemen.

Das Buch ist CC BY-SA 3.0 lizensiert und kann als Paperback ├╝ber lulu bezogen werden. Eine Vorversion in PDF-Format ist ebenfalls verf├╝gbar; da der Autor die Quellen selbst in monotone verwaltet, sollten auch diese demn├Ąchst verf├╝gbar sein.

Vielen Dank an Mathias f├╝r seine Bem├╝hungen!

Taxbird nun in MacPorts verf├╝gbar

Der ein oder andere kennt Stefan Siegls kleines Programm Taxbird eventuell schon: Es erleichtert Selbstst├Ąndigen unter Linux die Abgabe von Umsatzsteuervoranmeldungen gegen├╝ber dem ├Ârtlichen Finanzamt.

Mac-User blickten jedoch bislang weitesgehend in die R├Âhre, da der offizielle Elster-Client bis heute nur unter Windows verf├╝gbar ist. Da die Komponenten von Taxbird (die mit Gtk geschriebene GUI und eine Bibliothek zum Datentransfer, die auf den passenden Namen “libgeier” h├Ârt), Standard-Bibliotheken und Tools ben├Âtigt, habe ich mich an einen Port gemacht und diesen heute fertiggestellt.

Wer das ausprobieren m├Âchte, der m├Âge einfach sudo port install taxbird ausf├╝hren. Beim ersten Start erkundigt sich Taxbird nach html2ps, welches optional zur ├ťbersetzung des HTML-Reports in PostScript genutzt werden k├Ânnte. Ich habe hierf├╝r bislang auf einen weiteren Port verzichtet, da html2ps weder ├╝ber eine Standardinstallationsroutine verf├╝gt und au├čerdem etliche weitere Abh├Ąngigkeiten mit sich bringen w├╝rde. Die HTML-Reports sollten daher vor dem Versand einfach abgespeichert werden.

Feedback ist willkommen!

ACLs on Mac OS X

This is a short follow-up of an earlier post where I explained how one can set ACLs on FreeBSD. Today now I’ll do the same on another BSD variant, namely Mac OS X, and guess what, the guys from Cupertino implemented ACL management in a completely different manner.

The first thing to notice is that starting with Mac OS X 10.6 (Snow Leopard) ACLs are always enabled and cannot be disabled as in earlier versions. All ACL commands are baked into the chmod command and parsed from a string you give it with the ‘+a’ option. The basic syntax here is

$ chmod (+|-|=)a#? '<user> (allow|deny) <list-of-permissions>'

Since there is no setfacl on Mac OS X, there is no getfacl either, so ACLs are instead queried by the special option -e of ls:

$ ls -le .
-rw-r--r--+ 1 john users  175  5 Jun 00:23 foo
0: user:dave allow write

Permissions include the usual read, write, delete, add_file, and add_subdirectory as well as more exotic ones like {read,write}extattr, {read,write}writesecurity and chown. (Read up chmod‘s man page what these are for.)

There are, however, two more important ones to notice, namely file_inherit and directory_inherit. These two let you spread your permissions nicely to sub objects and thus let you for example set up a directory, in which a pool of users is allowed to access, modify and delete each other’s files:

$ chmod +a 'john allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit' /data
$ chmod +a 'dave allow read,write,delete,add_file,add_subdirectory,file_inherit,directory_inherit' /data

The above example gives john and dave inherited read, write and delete permissions to all file objects underneath /data.

Since ACLs are executed in order, they can also be set in an ordered manner. chmod has the +a# option for that, where # is the position into which the ACL should be added. Similarily, existing ACLs can be edited with =a#, where again # marks the position of the ACL to edit, and deleted with -a#.

Finally, if one wants to get rid of all ACLs of a specific node, chmod -N <path> will do the job.

Thats it, have fun playing with ACLs on Mac OS X!

SQLite to MySQL

Migrating a database dump from SQLite to MySQL can be somewhat of a hassle. After various trials I came up with the following that worked for me quite well:

echo .dump | sqlite3 mydb.db |\
  egrep -v "\b(BEGIN TRANSACTION|COMMIT|PRAGMA|sqlite_sequence)\b" |\
  perl -pe 's/^([^'\''"]*)"([^"]+)"/\1`\2`/' |\
  perl -pe 's/\bautoincrement\b/auto_increment/' |\
  mysql -uroot mydb

The most important line is probably line 3: SQLite encapsulates all table and column names in double quotes and this is not understood by MySQL, so we’re replacing them with backticks. One must be careful here, though, because data INSERTs might also contain double quotes and to avoid having these wrongly replaced as well we only replace them until we encounter the first single quote (these are used in SQLite to encapsulate strings).

Line 3 might also have to be called several times in a row in case multi-column indexes are part of the schema as well, as it will only replace the very first, but no subsequent matches. (I couldn’t get zero-width lookbehind to work properly to remedy this problem; help is welcome.)

jazzlib – an alternative for reading ZIP files in Java

Java had zip-reading capabilities for a long time, naturally because jar files are simply compressed zip files with some meta data. The needed classes reside in the java.util.zip namespace and are ZipInputStream and ZipEntry.

Recently, however, ZipInputStream gave me a huge headache. My use case was as simple as

  • read the zip entries of a list of zip files (each varying in size, but usually around 20MB)
  • skip to the zip entry that has a certain name (a single text file with only two bytes of contents)
  • read the contents of this zip entry and close the zip

Doing this for about 25 files took my Pentium D (2GHz) with 3GB of RAM roughly 20 seconds. Wow, 20 seconds really? I created a test case and profiled the code in question separately with YourKit (which is a really great tool, by the way!):

It got stuck quite a bit in java.util.zip.Inflater.inflateBytes – but that seemed to use native code, so I couldn’t profile any further.

So I went on and searched for an alternative of java.util.zip – and luckily I found one with jazzlib, which provides a pure Java implementation for ZIP compression and decompression. This library is GPL-licensed (with a small exception clause to prevent the pervasiveness of the GPL) and comes in two versions, one that duplicates the single library classes underknees java.util.zip (as a drop-in replacement for JDK versions where this is missing) and one that comes in its own namespace, net.sf.jazzlib.

After I went for the second version, I restarted my test and it only took about 7 seconds this time. At first I thought that there must be some downside to this approach, so I checked the timings for a complete decompression of the archive, but the timings here were on par with the ones from java.util.zip (roughly 5 seconds for a single 20MB file).

I haven’t tested compression speed, because it doesn’t matter much for my use case, but the decompression speed alone is astonishing. I wonder why nobody else stumbled upon these performance problems before…

mtn-browse 0.72 and accompanying Perl library released

Tony Cooper announced a new release of his Monotone Browser software and also a new version of the underlying Monotone::AutomateStdio Perl library.

Both packages are now compatible with the most recent version of monotone, 0.99.1. Additionally, mtn-browse also supports all the new selector functions introduced in monotone 0.99 and is able to restrict revision and file histories to specific branches.

Many thanks to Tony for his outstanding work! I’ll update the MacPorts packages in a few…

One framework to rule them all

I have a love/hate relationship with PHP; while I have talked in great length about all the badness that comes with it, I still find myself quite often writing and / or contributing to PHP applications. Most of this work was done with Symfony and, to a smaller degree, recently also with a relatively unknown framework called Pluf, which is the main building block for Indefero, the project and source code management tool I’m contributing to.

The author of Pluf, Loic d’Anterroches, has released a new framework to the wild today and its called Photon. It got its name from the particle, so naturally the tag line is “…because nothing is faster than a photon”.

So you are by now probably asking “Ok, but why should I care about that? There are dozens if not hundreds of PHP frameworks out there, they all claim to be fast, so this is probably just a complete waste of time…”

Well, Photon is very different, because it achieves its performance with a break of the traditionally known request-response model: Much like a real application server you know from other languages you can process requests asynchronously now in pure PHP, i.e. start and stop processes on request and delegate long-running work for later execution!

PHP developers did all kinds of bad tricks to emulate this stuff in the past. Most of these tricks employ a cache table and a cron entry that regularily executes some PHP script. This is buggy, doesn’t scale well and is of course plain ugly.

I won’t go into more details – just hop over to www.photon-project.com, read the docs and grab the pre-release while its hot!

Nazi-├ťberfall auf Wohnprojekt in Dresden

Ich bin eigentlich gegen jede Form von Gewalt, egal ob sie von links oder rechts kommt. Nach diesen schockierenden Bildern vom letzten Wochenende aber r├╝cke ich von meiner Position ab.

Unbelehrbaren Menschen muss Einhalt geboten werden – einer Horde von etwa 200 wildgewordenen Nazis, die 15 Minuten lang ein Wohnhaus in Dresden mit Steinen zu bewerfen, erst recht! Wie kann es sein, dass die Polizei – wenige Meter enfernt vom Ort des Geschehens positioniert – unf├Ąhig ist, Warnsch├╝sse abzufeuern oder auf eine andere Art einzugreifen, um diesen Treiben ein Ende zu bereiten?

Wenn der Gesetzgeber und die Polizei weiterhin so unwillens sind, nationalsozialistisch gesinnte Gewaltt├Ąter wirksam zu bek├Ąmpfen, dann sehe ich die autonome Linke in Zukunft als die letzte Bastion vor den marodierenden Rechtsradikalismus in diesem Land. Dann haben sie mich als Unterst├╝tzer, denn dann bin ich ganz klar f├╝r Selbstjustiz.