A plea to PHP developers.

This is a plea to PHP developers. Perl and Python web developers should heed similar advice because this really applies to MySQL development, and not PHP.

Please use mysql_connect() with no arguments. This causes it to get the database settings from the php.ini file, or perhaps, the my.cnf file.

What you are doing by letting the user enter a username, a password, and a host is almost certainly wrong, and if you read on I’ll try and explain why.

  1. The default on UNIX is to use a UNIX-domain socket: That’s part of the filesystem. On Debian this is in /var/run/mysqld/mysqld.sock and while there’s a certain magic in mysql that has led many PHP developers into thinking their script is working, it quite obviously breaks down when there are multiple MySQL installs on the same machine.
  2. The default is to use the information in the my.cnf file (or the php.ini file): This is a smaller part; hosting providers and network administrators can preload these with useful configurations. Using the defaults means your application will “just work”.
  3. TCP networking is a security risk: If an attacker can break your filesystem security, they can also replace your files and get your database username and password anyway. Enabling TCP networking just means that an attacker doesn’t have to do that anymore and can attack your database without having to also break your site.
  4. Passwords are a security risk: If you use a password, your password can be stolen. If no password will allow access to the database (say, using ssh-keys) then an attacker simply cannot get in.

Many apps ask for a username, a password, a host, and sometimes a port number. Unfortunately, there’s no way to enter the path to a UNIX domain socket which is required for a default build of MySQL that is simply installed in a nonstandard location.

None of these questions are required, of course, they’re useful if php.ini can’t be edited (ours can), or if .my.cnf can’t be edited or is wrong (ours isn’t), but this is an edge case- where your user is on a hosting provider which ships bad configuration by default.

If you can’t be bothered to trust the defaults, at least let the user pick a UNIX-domain socket, and ideally, get the information from the .my.cnf file likely in the user’s home directory. Do not require a hostname, a port number, or a password. Our systems don’t have any of these things, and hosting providers shouldn’t require any of these things.

I said PHP isn’t the problem; Perl has a similar problem, but it’s compounded somewhat. DBD::mysql doesn’t read the .my.cnf file by default. While in PHP I recommend that you do less work to make your users happier, on Perl, you have to do more work. In perl do something like this:

$dbh = DBI->connect("DBI:mysql:$db;mysql_read_default_file=$ENV{HOME}/.my.cnf");

…or better still, let your users specify their own DSN. It’s designed to be human-editable, and you’d be surprised just how little sugar-coating your users actually require.

netMail improvements

This was interesting.

One of our clients has a large Exchange deployment (by large, I mean more than 1000 seats) and decided they needed to satisfy another 800 mail users. Rather than immediately double their Microsoft licensing costs, they contacted us to see if we could do anything for them because it was only going to get worse- many of these mailboxes would be webmail-only users, and they had no existing OWA deployment.

Here’s what we did:

  • We created a subdomain netmail.example.com and set up our netMail web based email client
  • We installed a Linux box at the customer’s offices to download their address book using Samba’s net ads search '(showInAddressBook=*)' command and convert the result to VCard files. It then uploads the vcard file to their server here every 15 minutes.
  • Locally, anything in OU=TunnelledAddresses has a mailbox created for it. These addresses, which look like normal global address book entries in ADS simply have names like foobar@netmail.example.com which will tell Exchange to route them outside.
  • netMail is configured to send as example.com for each mailbox.

That’s it! None of these scripts required root access to our servers, which is a good way of demonstrating the flexibility of our messaging system. If you had a spare workstation you could install Ubuntu or Debian onto, you could do this yourself.

Everything you need to do this yourself is in mxtun.tgz, although if you had any questions, you could contact our support desk the usual way.