24 Dec 2011

Redirect root mail to external address in Debian

To redirect root mail to an external email just use /etc/aliases

# vi /etc/aliases

root: youremail@email.com

# newaliases
23 Aug 2011

Drop Foreign Key Constraint using INNODB

I recently needed to make some database modifications that required removing some existing foreign key constraints. The command looks like this.

ALTER table tablename DROP FOREIGN KEY foreign_key_name

MySQL was throwing errors.

mysql> ALTER TABLE reviews DROP FOREIGN KEY priority_id;
ERROR 1025 (HY000): Error on rename of ‘./dbname/reviews’ to ‘./dbname/#sql2-62f5-145b’ (errno: 152)

If you run

SHOW CREATE TABLE tablename

You’ll see the constraint names. You can then delete the foreign key based on the constraint.

ALTER TABLE tablename DROP FOREIGN KEY `reviews_ibfk_24`;

You can then drop the column as needed.

05 Aug 2011

MySQL Alter Table with InnoDB Foreign Key Constraint

In a recent project I needed to add a new table that would create a foreign key constraint on an existing table. I’m using the InnoDB storage engine. The existing table is employees and the new table is shifts. Shifts table is pretty simple.

CREATE TABLE shifts (
        id INT AUTO_INCREMENT NOT NULL,
        shift VARCHAR(15) NOT NULL,
        PRIMARY KEY(id)
) ENGINE=InnoDB;

The existing employees table needed a new column called “shift_id” that would reference the shifts table. The following code can be used to add the column and then add the foreign key constraint.

ALTER TABLE employees ADD shift_id INT AFTER group_id;
ALTER TABLE employees ADD CONSTRAINT FOREIGN KEY(shift_id) REFERENCES shifts(id) ON UPDATE CASCADE ON DELETE SET NULL;

The first alter statement worked fine, but the second kept throwing an error 150. You can view more details about the last error with the following:

SHOW INNODB STATUS;

I would see the following:

————————
LATEST FOREIGN KEY ERROR
————————
110805 8:49:16 Error in foreign key constraint of table backlogreviews/#sql-62f5_23:
FOREIGN KEY(shift_id) REFERENCES shifts(id) ON UPDATE CASCADE ON DELETE SET NULL:
Cannot resolve table name close to:
(id) ON UPDATE CASCADE ON DELETE SET NULL

This didn’t exactly help as I know the shifts table exists. I did some searching on google and found some hints, but these mostly indicated the column doesn’t match up correctly. Turns out I had a syntax error when creating the shifts table. The engine was INNOBD (notice the BD should read DB). Instead of throwing an error when creating the table it just used MyISAM. Since the storage engines didn’t match I was getting the error.

29 Jul 2011

Allow remote access to MySQL

I’m recently working on a project where I wanted to start playing with MySQL workbench to create an ER diagram for an existing database. I’m running Workbench on a Windows 7 machine with MySQL running on Ubuntu. Run the following to give the remote machine access.

mysql> grant all privileges on *.* to root@'remote_machone' identified by 'root password';
Query OK, 0 rows affected (0.12 sec)

You may not want to use the root account, but this will give you remote access.

27 Jul 2011

Password Hashing in CakePHP

In a recent project I needed to add some validation to my User model. I’m using the Auth Component that is included with CakePHP. In this particular instance I wanted to allow a change password form. The form would have three fields (current_password, new_password, confirm_password). In the Model I wanted to first check if the current password was entered correctly.

Validation should always happen in the model so I created a new function that would check for the current password for the logged in user. The Auth component automatically hashes the password with SHA1 and uses the Security Salt as part of the password string to create the hash, so I needed to hash the “current_password” field from the form to check for a match. This is where I ran into the problem. I tried using the following:

function checkCurrentPassword($data) {
    $id = $this->data[$this->alias]['id']; // passed the user ID from the form as a hidden field
    $pwd = $this->field('password', array('id' => $id)); // get the current password from the database
    if(Security::hash($data['current_password']) != $pwd) {
        return false;
    }
    return true;
}

You can see that $id is passed from the form and $pwd is a variable for the current password in the database. Auth will automatically hash an input with the name “password”, but my form is using “current_password”, so it is sent in cleartext. This needs to be hashed first. I attempted to use the Security::hash function but my validated kept failing.

As it turns out the Security::hash function is only using SHA1 without the Security Salt added. What I was able to do is use the AuthComponent::password function instead which does use the Security Salt configured in core.php. New code looks like:

function checkCurrentPassword($data) {
    $id = $this->data[$this->alias]['id'];
    $pwd = $this->field('password', array('id' => $id));
    if(AuthComponent::password($data['current_password']) != $pwd) {
        return false;
    }
    return true;
}

The validate array would look like this:

var $validate = array(
'current_password' => array(
    'rule' => 'checkCurrentPassword',
    'message' => 'Current password was not entered correctly'
    )
);

Update: Security::hash actually takes a third parameter documented in the API to use the Security.salt value

Create a hash from string using given method. Fallback on next available method.

Parameters:

string $string required

String to hash
string $type optional NULL

Method to use (sha1/sha256/md5)
boolean $salt optional false

If true, automatically appends the application’s salt value to $string (Security.salt)

17 Jul 2011

Cakephp form input using select with options

There are times that you need to control the form->input helper with specific type setting and additional options. This is probably more comment when building custom form inputs that aren’t automagically being set from the model/controller.

I recently had to build a list on distinct dates, but prefer to user $this->Form->input, rather than $this->Form->select. I first built an indexed array containing my date fields.

array(
[xxxx-xx-xx] => xxxx-xx-xx
[yyyy-yy-yy] => yyyy-yy-yy
)

We’ll call this array $options. You can then build the input using something like

$this->form->input('Input Name', array(
  'type' => 'select',
  'options' => 'options',
  'label' => 'label',
  'empty' => 'No data selected'
);
30 Jun 2011

CakePHP 1.3 Virtual Fields

A new feature of CakePHP 1.3 is to create VirtualFields. Why do you care? Typically Cake can use the $displayField variable of a model for drop down lists in your views. Suppose a User model contains two columns, firstname and lastname. There is no way to concatenate this with the $displayField variable. You can however, use $virtualFields to create a new variable that can be assigned to $displayField.

My example uses an Employee model.

class Employee extends AppModel {
	var $name = 'Employee';
        var $virtualFields = array('full_name' => 'CONCAT(Employee.firstname, " ", Employee.lastname)');
        var $displayField = 'full_name';
}
17 Apr 2011

Recover Ubuntu Boot Problems

I recently had a problem with my development machine. I haven’t used it in a while and realized I could not VNC or SSH to the box. This is a headless machine so I had to plugin a monitor and keyboard to see what was happening. I was greeted with the following:

Target file system doesn’t have /sbin/init
No init found. Try passing init= bootarg

Busybox v1.13.3 (Ubuntu 1:1.13.3-1ubuntu7) built-in shell (ash)
Enter ‘help’ for a list of built-in commands
(initramfs) _

Not very happy about this. Running “help” didn’t reveal any tools that would repair the boot volume. To recover I booted to an Ubuntu 10.10 CD and select the option to “Try Ubuntu”. Once this started I used Ctrl + Alt + F1 to get to a shell and ran the following:

sudo fdisk -l
sudo fsck /dev/sda1

Running fdisk -l was just to be sure of the naming convention for my main drive, which in this case was /dev/sda1. I had to enter yes a couple times and then rebooted the machine which loaded successfully.

05 Mar 2011

Testing Database Connectivity

On windows you can simply create an empty file and give an .UDL extension. This will open a dialog to test DB connections.

Testing Database Connectivity with UDL File

14 Nov 2010

Build pure-ftpd for Debian Lenny running on OpenVZ

Capabilities on OpenVZ causes pure-ftpd not to start when installing with the package manager. Use the following method to download the source and build pure-ftpd without capabilities.

mkdir /usr/src/pure-ftpd
cd /usr/src/pure-ftpd

apt-get source pure-ftpd
apt-get build-dep pure-ftpd

Edit the rules file and add the following to optflags [--without-capabilities]

cd pure-ftpd-1.0.21/debian
vi rules

optflags=–with-everything –with-largefile –with-pam –with-privsep –with-tls –without-capabilities

Build the package and install it.

cd ..
dpkg-buildpackage -uc -b

cd ..
dpkg -i pure-ftpd-common_1.0.21-11.4_all.deb pure-ftpd-mysql_1.0.21-11.4_i386.deb
/etc/init.d/pure-ftpd-mysql restart

Prevent the package manager from trying to update pure-ftpd

echo 'pure-ftpd-common hold' | dpkg --set-selections
echo 'pure-ftpd-mysql hold' | dpkg --set-selections