MySQLAuth External Authentication Module for SurgeMail

An external authentication module that allows SurgeMail to do user lookups on a MySQL Database.


A step by step example of creating a MySQLdatabase on NT

Below is an unedited example of setting up a MySQL database to test on a Windows NT box.

1. Downloaded from a MySQL mirror site (they like it when you use a mirror),
mysql-shareware-3.22.32.win.zip
and unpacked to,
d:\mysql

2. Edited example file, d:\mysql\my-example.cnf that came with it, so that, all c:'s were changed to d:, and saved as,
c:\my.cnf
(notepad named it c:\my.cnf.txt for me so I did a rename on it in a dos prompt)

3. In order to install as service on NT...

d:\mysql\bin>mysqld-shareware --install

NB: when I then tried to start service in ControlPanel|Services, it failed with a message saying that the process had stopped itself.

so I entered...

d:\mysql\bin>mysqld-shareware --debug
and at the top of all the mess was an error about a setting in the my.cnf file that it did not like.

NB: If I ran it from a command line, it started and could not be stopped, even with a CTRL-C - I had to kill it inprocess list of task manager. In the bin dir was an exe mysqlshutdown, which just popped up a window (Icon in system tray), but I could not get it to stop the process - maybe it is for stopping the service? - no does not seem to affect that either - kind of a cute icon though :-)
The dos command,
net stop mysql
does work as does,
net start mysql
.

4. Creating root user.

NB: our SQLAuth module makes you send a password. By default, the MySQL daemon has a root user with no password, so you need to set the root password to something.

From the MySQL manual ...
(The following example starts by removing the anonymous user. That allows anyone to access the 'test' database)

d:\mysql\bin\mysql mysql
mysql> DELETE FROM user WHERE Host='localhost' AND User='';
mysql> QUIT
d:\mysql\bin\mysqladmin reload
d:\mysql\bin\mysqladmin -u root password your_password

NB: I had problems getting the root password set after deleting it. I ended up entering the following to set the root password...

D:\mysql\bin>mysqlc -u root mysql
Reading table information for completion of table and column names

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16 to server version: 3.22.32-shareware-debug

Type 'help' for help.

mysql> UPDATE user SET Password=PASSWORD('qwerty') WHERE user='root';
Query OK, 2 rows affected (0.02 sec)
Rows matched: 2 Changed: 2 Warnings: 0

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.03 sec)

Now in c:\my.cnf edit client section and add,
password=qwerty
and save.

Now you should be able to connect with the client program as user root with the new password...

5. Now follow the examples in the manual.

In section 8.4 of the manual file,
d:\mysql\docs\manual.htm
start client (on local machine - same as ...

D:\mysql\bin>mysqlc -u root -pqwerty

(can also do,
D:\mysql\bin>mysqlc -u root -p
and it prompts for password so that your command prompt buffer does not contain your password if you are worried about that sort of security)

(on non-local machine,
D:\mysql\bin>mysqlc -u root -pqwerty -host=1.2.3.4
)

(NB: you can also include a database name on the end of the line to connect to a specific database, eg: to connect to a database called, 'mydb' enter,
D:\mysql\bin>mysqlc -u root -pqwerty mydb
)

every time you see 'mysql>' from now on, it indicates that you are at the prompt in the mysqlc client program...

6. Create test database and a table within it ...

mysql> CREATE DATABASE maildb;
Query OK, 1 row affected (0.01 sec)

mysql> CREATE TABLE maildb (username VARCHAR(20),password VARCHAR(20),forward VARCHAR(20));
Query OK, 0 rows affected (0.03 sec)

mysql> SHOW TABLES;

+------------------+
| Tables in maildb |
+------------------+
| maildb           |
+------------------+
1 row in set (0.01 sec)

mysql> DESCRIBE maildb;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| username | varchar(20) | YES  |     | NULL    |       |
| password | varchar(20) | YES  |     | NULL    |       |
| forward  | varchar(20) | YES  |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.01 sec)

7. Loading users in from a text file ...

I then made a file d:\mysql\users.txt which looked like,

tam pass \N
test test \N

where \N stands for NULL meaning no entry for that field. and then tried to load it. You'll see I assumed a few things about file paths incorrectly. I remember reading in the manual somewhere about using / instead of \ (or using \\).

mysql> LOAD DATA LOCAL INFILE "users.txt" INTO TABLE maildb;
ERROR: File 'users.txt' not found (Errcode: 2)
mysql> LOAD DATA LOCAL INFILE "d:\MYSQL\users.txt" INTO TABLE maildb;
ERROR: File 'd:MYSQLusers.txt' not found (Errcode: 2)
mysql> LOAD DATA LOCAL INFILE "d:/MYSQL/users.txt" INTO TABLE maildb;
Query OK, 2 rows affected (0.02 sec)
Records: 2 Deleted: 0 Skipped: 0 Warnings: 0

8. Inserting a single record/updating a field/encrypting passwords ...

(use 'NULL' where you don't have an entry for a field)

mysql> INSERT INTO maildb VALUES ('bob','bob','NULL');
Query OK, 1 row affected (0.01 sec)

oops - should have encrypted the password ...

mysql> UPDATE maildb SET password = PASSWORD('bob') WHERE username = 'bob';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0

so how do I add from text file and encrypt the passwords ...?

I can't work out how to do this, so I had better encrypt all the other passwords ...

mysql> UPDATE maildb SET passwd = PASSWORD('tam') WHERE username = 'tam';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> UPDATE maildb SET passwd = PASSWORD('test') WHERE username = 'test';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0

Now, let's see what I have in my maildb database ...

mysql> SELECT * FROM maildb;

+----------+------------------+---------+
| username | password         | forward |
+----------+------------------+---------+
| tam      | 6752d6483e543e43 | NULL    |
| test     | 378b243e220ca493 | NULL    |
| bob      | 7d67547927a4589e | NULL    |
+----------+------------------+---------+
3 rows in set (0.01 sec)

oops - I gave the wrong name to my table column 'password' ...

8. Changing a table column name ...

mysql> ALTER TABLE maildb CHANGE 'password' 'passwd' VARCHAR(20);
ERROR 1064: You have an error in your SQL syntax near ''password' 'passwd' VARCH
AR(20)' at line 1
mysql> ALTER TABLE maildb CHANGE password passwd VARCHAR(20);
Query OK, 3 rows affected (0.19 sec)
Records: 3 Duplicates: 0 Warnings: 0

Now let's see what is in my maildb database again ...

mysql> SELECT * FROM maildb;

+----------+------------------+---------+
| username | passwd           | forward |
+----------+------------------+---------+
| tam      | 6752d6483e543e43 | NULL    |
| test     | 378b243e220ca493 | NULL    |
| bob      | 7d67547927a4589e | NULL    |
+----------+------------------+---------+
3 rows in set (0.01 sec)


A step by step example of creating a MySQLdatabase on Solaris

Went to Australian mirror of http://mysql.com , http://mirror.aarnet.edu.au/mysql and downloaded,

mysql-3.23.32-sun-solaris2.7-sparc.tar.gz
then umpacked to /usr/local with, gzip -d mysql-3.23.32-sun-solaris2.7-sparc.tar.gz (I had already retrieved gzip for solaris from the sun freeware site, see instructions for getting GNU tar below for details)

I tried to untar but failed, apparently because of a bug in solaris tar.

So I upgraded to GNU tar by...

# cd /usr/local/ # ftp sunfreeware.davnet.com.au
(login with username) anonymous
(give email address) my_email_address
ftp> bin
ftp> hash
ftp> cd pub/freeware/sparc/7
(NB: I am running solaris 7)
ftp> get tar-1.13-sol7-sparc-local.gz
ftp> quit
Then add package with
# gzip -d tar-1.13-sol7-sparc-local.gz
# pkgadd -d tar-1.13-sol7-sparc-local
(selected pressed return twice for,
1. install all packages
2. allow it to overwrite attributes on some files already there (I presume they
were the old tar)
)
Untared with,
tar -xvf mysql-3.23.32-sun-solaris2.7-sparc.tar
Then followed relevant instructions on page,
http://mirror.aarnet.edu.au/mysql/doc/I/n/Installing_binary.html
ie:
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> cd /usr/local
had already done this, shell> gunzip < /path/to/mysql-VERSION-OS.tar.gz | tar xvf -
shell> ln -s mysql-VERSION-OS mysql
shell> cd mysql
shell> scripts/mysql_install_db
{

# scripts/mysql_install_db
Preparing db table
Preparing host table
Preparing user table
Preparing func table
Preparing tables_priv table
Preparing columns_priv table
Installing all prepared tables

In order to start mysqld at boot time, you have to copy support-files/mysql.server
to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
This is done with:
./bin/mysqladmin -u root -p password 'new-password'
./bin/mysqladmin -u root -h fluffy -p password 'new-password'
See the manual for more instructions.

Please report any problems with the ./bin/mysqlbug script!

The latest information about MySQL is available on the web at
http://www.mysql.com
Support MySQL by buying support/licenses at https://order.mysql.com


}
shell> chown -R mysql /usr/local/mysql
shell> chgrp -R mysql /usr/local/mysql
shell> bin/safe_mysqld --user=mysql &

(If you want to install support for the Perl DBI/DBD interface, see section 4.11 Perl Installation Comments. )

# bin/safe_mysqld --user=mysql &
[1] 7710
# Starting mysqld daemon with databases from /usr/local/mysql-3.23.32-sun-solaris2.7-sparc/data
Abort
010202 11:30:07 mysqld ended

Hmmm, seems not to be working when I do, ps -ef |grep mysql, so find manual section,
4.16.2 Problems Starting the MySQL Server
which informs me that log is in,

/usr/local/mysql/data/servername.err

which has,
010202 12:00:00 mysqld started
010202 12:00:00 bdb: /usr/local/mysql-3.23.32-sun-solaris2.7-sparc/dataalog.00
00000001: Permission denied

So check permissions...

# ls -l
total 18
drwxr-xr-x 2 502 1003 1024 Jan 22 18:56 bin
drwxr-x--- 4 502 1003 512 Feb 2 11:30 data
drwxr-xr-x 2 502 1003 1024 Jan 22 18:56 include
drwxr-xr-x 2 502 1003 512 Jan 22 18:56 lib
drwxr-xr-x 2 502 1003 512 Jan 22 18:56 scripts
drwxr-xr-x 3 502 1003 512 Jan 22 18:56 share
drwxr-xr-x 5 502 1003 512 Feb 2 10:41 sql-bench
drwxr-xr-x 2 502 1003 512 Jan 22 18:56 support-files
drwxr-xr-x 2 502 1003 512 Jan 22 18:56 tests
and when su to the MySQL users,
# cd data
bash: cd: data: Permission denied
but,
chown -R mysql mysql
should have recursed all dirs - perhaps the solaris chown only goes one level deep?!
so did,
cd /usr/local/mysql
chwon -R mysql ./*
chgrp -R mysql ./*
then as root user I try again,
bin/safe_mysqld --user=mysql &
and get,
# Starting mysqld daemon with databases from /usr/local/mysql-3.23.32-sun-solaris2.7-sparc/data (I pressed enter here) #
Yay!

Now did the tests from the manual,

shell> bin/mysqladmin version
shell> bin/mysqladmin variables

In order to use MySQLAuth, you have to have set the root password, so ...
using the instructions given above,

# bin/mysqladmin -u root -p password 'qwerty' Enter password: (I pressed enter here as there was no password currently set) #

So root password should now be 'qwerty'
check with,

# bin/mysqladmin version
bin/mysqladmin: connect to server at 'localhost' failed
error: 'Access denied for user: 'root@localhost' (Using password: NO)'
and it fails when it did not before, so try,
# bin/mysqladmin -u root -p version
Enter password: (enter qwerty here)
and it worked. Success.

Test running SQL client,

# bin/mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11 to server version: 3.23.32

Type 'help;' or '\h' for help. Type '\c' to clear the buffer

mysql> select version(), current_date;


+-----------+--------------+
| version() | current_date |
+-----------+--------------+
| 3.23.32   | 2001-02-02   |
+-----------+--------------+
1 row in set (0.02 sec)

mysql>
Success.

Now test MySQLAuth from NT box with c:\winnt\system32\mysqlauth.ini of,

# Welcome to MySQLAuth ini File.
# Leading # makes line a comment
# Save this file to /etc/mysqlauth.ini or c:\winnt\system32\mysqlauth.ini or
# in same directory as executable.
# Manual page is at, http://www.netwinsite.com/authent/mysqlauth.htm
# -------------------------------------------------------------------------------------

# IP address of server to connect to:
mysql_server 10.0.0.2
# Login username and password:
mysql_login root
mysql_password qwerty

# MySQL Table Field Names
# ---------------------
field_username username
field_password passwd
field_forward forward

# Other common INI settings for MySQLAuth
# --------------------------
# debug true
log true
log_path c:\surgemail\mysqlauth.log
# domain test.com
# mysql_mail_user_db maildb
# mysql_mail_user_table maildb

and enter,

cd \surgemail
MySQLAuth
and get error,
-ERR: Cannot Connect to 10.0.0.2 as root
try,
telnet 10.0.0.2 3306
and get,
'server_name' is not allowed to connect to this MySQL server

So we need to allow access...

mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature in order to get a quicker startup with -A

Database changed
mysql> select database();


	+------------+
	| database() |
	+------------+
	| mysql      |
	+------------+
	1 row in set (0.00 sec)

	mysql> show tables;
	+-----------------+
	| Tables_in_mysql |
	+-----------------+
	| columns_priv    |
	| db              |
	| func            |
	| host            |
	| tables_priv     |
	| user            |
	+-----------------+
	6 rows in set (0.00 sec)

	mysql> select * from user;
	+-----------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
	| Host      | User | Password         | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv |
	+-----------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
	| localhost | root | 009094026f11b5c7 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
	| fluffy    | root |                  | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
	| localhost |      |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
	| fluffy    |      |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
	+-----------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
	4 rows in set (0.00 sec)
	
Manual says to use commands rather than touching the table directly. Want to change host from,
localhost
to
10.0.0.*
(or maybe the special char % to allow connections from anywhere) so,
mysql> GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
Oops I did not put in the correct password. so now I have,
mysql> select * from user;

+-----------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
| Host      | User | Password         | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv |
+-----------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
| localhost | root | 009094026f11b5c7 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
| fluffy    | root |                  | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
| localhost |      |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
| fluffy    |      |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
| %         | root | 0fc756bc026507b2 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
+-----------+------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
5 rows in set (0.01 sec)
where root connecting from anywhere can use password some_pass, and if connecting locally can use qwerty!

So now try adding a special user, SurgeMail password of mail,

mysql> GRANT ALL PRIVILEGES ON *.* TO surgemail@"%" IDENTIFIED BY 'mail' WITH GRANT OPTION;
NB: GRANT is implemented in MySQL Version 3.22.11 or later. For earlier MySQL versions, the GRANT statement does nothing.

mysql> select * from user;
+-----------+-------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
| Host      | User  | Password         | Select_priv | Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv | Reload_priv | Shutdown_priv | Process_priv | File_priv | Grant_priv | References_priv | Index_priv | Alter_priv |
+-----------+-------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
| localhost | root  | 009094026f11b5c7 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
| fluffy    | root  |                  | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
| localhost |       |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
| fluffy    |       |                  | N           | N           | N           | N           | N           | N         | N           | N             | N            | N         | N          | N               | N          | N          |
| %         | root  | 0fc756bc026507b2 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
| %         | surgemail | 64d94ec17fb953a4 | Y           | Y           | Y           | Y           | Y           | Y         | Y           | Y             | Y            | Y         | Y          | Y               | Y          | Y          |
+-----------+-------+------------------+-------------+-------------+-------------+-------------+-------------+-----------+-------------+---------------+--------------+-----------+------------+-----------------+------------+------------+
6 rows in set (0.00 sec)

(and can revoke them again,

mysql> REVOKE ALL PRIVILEGES ON *.* FROM surgemail@"%";
mysql> flush privileges;
)

Let's try from local box, so on solaris box set /etc/mysqlauth.ini as above but change,

mysql_server 10.0.0.2
to
mysql_server 127.0.0.1
just to be sure connecting locally. we get,
# ./mysqlauth
-ERR: Cannot Connect to database maildb
so connection to the server was successfull, now we need to add an appropriate database and table as per the NT example above.