Postfix + MySQL Virtual User Script
Here’s a script I wrote for myself and my friend to help add virtual mail users in a Postfix w/ MySQL setup:
#!/usr/bin/perl
use Term::ReadKey;
use Email::Valid;
use Mysql;
# SETTINGS
$DEBUG = true;
$USER_TABLE = "users";
$VIRT_TABLE = "virtual";
$TRAN_TABLE = "transport";
# User Table Columns
$ADDR_COL = "address";
$PASS_COL = "crypt";
$NAME_COL = "name";
$DOMAIN_COL = "domain";
$HOME_COL = "home";
$MAILDIR_COL = "maildir";
$ENABLED_COL = "imapok";
# Transport Table Columns
$TRAN_DOMAIN_COL = "domain";
$TRAN_TRANSPORT_COL = "transport";
$TRAN_VIRTUAL_TRANSPORT = "virtual:";
$DB_USER = "mail";
$DB_PASS = "";
$DB_NAME = "mail";
$VMAIL_ROOT = "/home/vmail";
$DEFAULT_UID = 106;
$DEFAULT_GID = 111;
# Variables
my $address;
my $password;
my $homedir;
my $maildir;
my $fullname;
my $domain;
my $user_exists = 0; # If the user is already in the database
# If need be, get the DB user's password
if ($DB_PASS eq "") {
print 'Database Password: ';
ReadMode('noecho');
$DB_PASS = ReadLine(0);
ReadMode('restore');
print "\n";
chomp $DB_PASS;
}
# Connect to the database
$db = Mysql->connect("localhost", $DB_NAME, $DB_USER, $DB_PASS);
# Get an array of all virtual user domains
$query = "SELECT $TRAN_DOMAIN_COL FROM $TRAN_TABLE WHERE $TRAN_TRANSPORT_COL='$TRAN_VIRTUAL_TRANSPORT'";
$result = $db->query($query);
my @domains = $result->fetchcol(0);
sub check_address {
$ret = 0;
foreach $fqdn (@_) {
$search = "/\@$fqdn\$/";
print $search . "\n";
if ($address =~ $search) {
$ret = 1;
}
}
return $ret;
}
# Get the user's email address
do {
print "Address: ";
$address =
chomp $address;
} while (!Email::Valid->address($address));
# Get user info from database, if exists
$sel_query = “SELECT * FROM $USER_TABLE WHERE $ADDR_COL = ‘$address’”;
$result = $db->query($sel_query);
# If there was a row returned…
if ($result->numrows != 0) {
%array = $result->fetchhash;
do {
print “User exists. Really change password (Y/N)? “;
$yn =
chomp $yn;
} while ($yn !~ /^[ynYN]$/);
exit 0 if $yn =~ /^[Nn]/;
$user_exists = 1;
}
print ‘Password: ‘;
ReadMode(’noecho’);
$password = ReadLine(0);
ReadMode(’restore’);
print “\n”;
chomp $password;
if ($user_exists) {
print ‘Full Name: ‘;
$fullname =
chomp $fullname;
}
($name, $domain, $tld) = ($address =~ /(^.+)@(.+)\.(.+?)$/);
$domaintld = $domain . “.” . $tld;
$homedir = $VMAIL_ROOT . “/” . $domain . “/” . $name . “/”;
$maildir = $homedir . “Maildir/”;
my $query;
if ($user_exists) {
$query = “UPDATE $USER_TABLE SET”
. ” $PASS_COL=ENCRYPT(’$password’)”
. ” WHERE $ADDR_COL=’$address’”;
} else {
$query = “INSERT INTO $USER_TABLE SET”
. ” id=’$address’”
. “, $ADDR_COL=’$address’”
. “, $PASS_COL=ENCRYPT(’$password’)”
. “, $NAME_COL=’$fullname’”
. “, $HOME_COL=’$homedir’”
. “, $MAILDIR_COL=’$maildir’”
. “, $DOMAIN_COL=’$domaintld’”
. “, $ENABLED_COL=1″;
}
$db->query($query);
if ($user_exists) {
} else {
print `mkdir $homedir` . “\n”;
print `maildirmake $maildir` . “\n”;
print `chown -R $DEFAULT_UID:$DEFAULT_GID $homedir`;
}