Chris Jean's Blog

Linux, WordPress, programming, anime, and other stuff.
twitter
rss

Archive for May, 2010

I’m working on building an ideal server setup that allows for both PHP 4 and PHP 5 on Apache with suPHP (I’ll blog about this later). While testing my PHP 4 build, I got the following error:

Warning: mysql_connect() [function.mysql-connect]: Client does not support authentication protocol requested by server; consider upgrading MySQL client in /var/www/test-php.php on line 3
Couldn’t authenticate with MySQL

The code I used to test this is quite simple:

<?php

if ( false === ( $db = mysql_connect( 'localhost', 'username', 'password' ) ) )
    die( "Couldn't authenticate with MySQL" );

if ( false === mysql_select_db( 'database' ) )
    die( "Couldn't connect to database" );

echo "Yay!";

?>

After digging around for a bit, I found that mixing PHP 4 with a MySQL version greater than or equal to 4.1 causes this problem. MySQL 4.1 introduced a new password caching scheme that PHP 4 can’t work with.

The solution is to update the database user’s password using the OLD_PASSWORD function of MySQL. For example:

[chris@office ~]$ mysql -u root -p mysql
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 267
Server version: 5.1.41-3ubuntu12.1 (Ubuntu)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> update user set Password=OLD_PASSWORD('password') WHERE User='username';
Query OK, 0 rows affected (0.02 sec)
Rows matched: 0  Changed: 0  Warnings: 0

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql>

Note the underlined areas. That is where you’ll want to provide your own username and password.

Once you’ve followed these steps, both PHP 4 and PHP 5 will be able to communite with the database.

Thanks to digitalpeer for providing the answer to my issue.

I recently had a issue getting MySQL to read a specific database. Each time I tried to manually query a table in the database, I received the following error message:

ERROR 1018 (HY000): Can't read dir of './default/' (errno: 13)

I’ve seen this message before as it means that there is a permissions issue. I checked the ownerships and permissions, and everything seemed to be in order.

The only thing special about this database is that I have it symlinked to another partition. This has always worked in the past, so I was stumped.

The problem turned out to be that Ubuntu has AppArmor. This software sets up rules that prevent software from gaining access to different areas of the file system. In my case, AppArmor was preventing read and write access to the actual location of my database files.

The solution was quite easy: First, I added the path that I wanted MySQL to have access to in the AppArmor configuration file for MySQL. Second, I restarted the apparmor service. Here’s the technical details:

  1. On my system, the configuration file that controls MySQL permissions through AppArmor are located at /etc/apparmor.d/usr.sbin.mysqld. The following shows the contents of the file as it now exists:
    # vim:syntax=apparmor
    # Last Modified: Tue Jun 19 17:37:30 2007
    #include 
    
    /usr/sbin/mysqld {
      #include
      #include
      #include
      #include
      #include 
    
      capability dac_override,
      capability sys_resource,
      capability setgid,
      capability setuid,
    
      network tcp,
    
      /etc/hosts.allow r,
      /etc/hosts.deny r,
    
      /etc/mysql/*.pem r,
      /etc/mysql/conf.d/ r,
      /etc/mysql/conf.d/* r,
      /etc/mysql/my.cnf r,
      /usr/sbin/mysqld mr,
      /usr/share/mysql/** r,
      /var/log/mysql.log rw,
      /var/log/mysql.err rw,
      /var/lib/mysql/ r,
      /var/lib/mysql/** rwk,
      /var/log/mysql/ r,
      /var/log/mysql/* rw,
      /var/run/mysqld/mysqld.pid w,
      /var/run/mysqld/mysqld.sock w,
      /home/sites/default/mysql/ rw,
      /home/sites/default/mysql/* rw,
    
      /sys/devices/system/cpu/ r,
    }

    The two lines in bold show what I added to the configuation. The first line gives read and write access to the directory itself while the second gives read and write access to the files contained in the directory.

  2. After saving the configuration changes, I simply needed to restart the AppArmor daemon. I did this with the following command:
    [chris@rommie ~]$ sudo service apparmor restart
     * Reloading AppArmor profiles
    Skipping profile in /etc/apparmor.d/disable: usr.bin.firefox