Created today a little .php script (and guide) for a bulk creation of mailboxes.
Tested with the actual mailcow version and 111 mailboxes. Is a bulk insert function planned for mailcow? If not: Maybe this is something for the documentation 😊
This guide is created to show an easy way to bulk insert a lot e-mail user into your mailcow.
Tested with Mailcow Dockerized (30.11.2017).
Migration from files is not included. Please use the Sync Function or a tool like imapsync.
This script will keep every data on your mailcow server. It never heard something from the cloud. (Yes, it is dump 😉 )
cd /path/to/mailcow-dockerizedsource mailcow.conf
DATE=$(date +"%Y%m%d_%H%M%S")
docker-compose exec -T mysql-mailcow mysqldump --default-character-set=utf8mb4 -u${DBUSER} -p${DBPASS} ${DBNAME} > backup_${DBNAME}_${DATE}.sql
$user_array = [
['Name', 'Surname', 'user', 'Password', 'E-mail', 'Domain'],
['Name2', 'Surname2', 'user2', 'Password2', 'E-mail2', 'Domain2'],
];
alias VALUESmailbox VALUESquota2 VALUESuser_acl VALUESsource mailcow.conf
docker exec -i $(docker-compose ps -q mysql-mailcow) mysql -u${DBUSER} -p${DBPASS} ${DBNAME} < bulk-import.sql
10.2. Wait until it is done
Now you can login with the user credentials!
<?php
/* ['Name', 'Surname', 'user', 'Password', 'E-mail', 'Domain'], */
$user_array = [
['Name', 'Surname', 'user', 'Password', 'E-mail', 'Domain'],
['Name2', 'Surname2', 'user2', 'Password2', 'E-mail2', 'Domain2'],
];
?>
<html>
<head>
<title>Mailcow Bulk SQL Generator for Mailboxes</title>
</head>
<body>
<?php
include 'inc/functions.inc.php';
include 'mcb_user_array.php'; /* Contains an array with the user data */
/* Mysql Strings */
$mysql_mailbox = 'INSERT INTO `mailbox` VALUES ';
$mysql_alias = 'INSERT INTO `alias` VALUES ';
$mysql_quota2 = 'INSERT INTO `quota2` VALUES ';
$mysql_user_acl = 'INSERT INTO `user_acl` VALUES ';
$date = date("Y-m-d H:i:s");
$dir_size = 512 * 1024 * 1024; /* 512 MB */
$fullname = ''; /* Created automaticly */
$password_hash = ''; /* Hashed password */
$i = 0;
$name = ''; /* From Array */
$surname = ''; /* From Array */
$user = ''; /* From Array */
$password = ''; /* From Array */
$email = ''; /* From Array */
$domain = ''; /* From Array */
$array_len = count($user_array);
/* Read in Array */
foreach($user_array as list($name, $surname, $user, $password, $email, $domain)) {
$i++;
$fullname = "$name $surname";
$password_hash = hash_password($password);
/* Insert information for mysql string */
$mysql_mailbox .= "('$email','$password_hash','$fullname','$domain/$user/',$dir_size,'$user','$domain',0,0,'',0,0,'$date',NULL,1)";
$mysql_alias .= "('$email','$email','$domain','$date',NULL,1)";
$mysql_user_acl .= "('$email',1,1,1,1,1,1,1,1,1,1)";
$mysql_quota2 .= "('$email',0,0)";
if ($i == $array_len) {
$mysql_mailbox .=";";
$mysql_quota2 .=";";
$mysql_alias .=";";
$mysql_user_acl .=";";
} else if ($i > 0) {
$mysql_mailbox .=",";
$mysql_alias .=",";
$mysql_quota2 .=",";
$mysql_user_acl .=",";
}
}
/* Print result */
echo "<h5>alias | Around Line 71</h5>$mysql_alias"; /* Around Line 71 */
echo "<h5>Mailbox | Around Line 334</h5>$mysql_mailbox"; /* Around Line 334 */
echo "<h5>quota2 | Around Line 359</h5>$mysql_quota2"; /* Around Line 359 */
echo "<h5>user_acl | Around Line 856</h5>$mysql_user_acl"; /* Around Line 856 */
?>
</body>
</html>
I believe $mysql_user_acl .= "('$email',1,1,1,1,1,1,1,1)"; must be $mysql_user_acl .= "('$email',1,1,1,1,1,1,1,1,1,1)";. (10 instead of 8 ones.)
You are right. Thank you!
In one of the lastest versions two new values were added.
Updated the row in the guide.
Another little thing: Chrome and Firefox don't show anything for me because </title> is missing.
Sounds like you should create a PR with this functionality.
@Braintelligence I think a API (There's already something on https://mail.example.com/api/v1/add/mailbox, but we can not use it in in a script because thy ned a CSRF token) were nice. Or a form in mailcow for bulk adding.
Or a form in mailcow for bulk adding.
That's what I meant.
Everything exits. I just haven’t enabled it yet. Stupid docs. :-)
@mritzmann Oh, this got lost, for some reason, while I create the little guide. But in a time x it is no longer needed.
I will fix the guide in the next seconds.
Everything exits. I just haven’t enabled it yet. Stupid docs. :-)
I look forward to it. Need the possibility in the next few days. :-)
I wanted to add users from bash so I added a function and a procedure to the mariadb database so i can add users with isql. Maybe someone will find this useful:
DELIMITER $$
CREATE DEFINER=`mailcow`@`%` FUNCTION `mailcow_password`(_password varchar(128),_salt char(16)) RETURNS varchar(128) CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci
BEGIN
if _salt IS NULL then
set _salt=HEX(CONCAT(CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256)));
elseif LENGTH(_salt)<>16 then
set _salt=HEX(CONCAT(CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256),CHAR(RAND()*256)));
end if;
--
RETURN CONCAT('{SSHA256}',TO_BASE64(UNHEX(CONCAT(SHA2(CONCAT(_password,_salt),256),HEX(_salt)))));
END$$
DELIMITER ;
DELIMITER $$
CREATE DEFINER=`mailcow`@`%` PROCEDURE `add_mailbox`(_user varchar(80), _domain varchar(80), _password varchar(80), _name varchar(80), _surname varchar(80),_quota_bytes integer)
BEGIN
declare _email varchar(128);
declare _full_name varchar(128);
declare _maildir varchar(128);
--
set _email=CONCAT(TRIM(_user),'@',TRIM(_domain));
set _full_name=CONCAT(TRIM(_name),' ',TRIM(_surName));
set _maildir=CONCAT(TRIM(_domain),'/',TRIM(_user));
-- mailbox
INSERT INTO mailbox(username,password,name,maildir,local_part,domain,quota,attributes)
VALUES(_email, mailcow_password(_password,null),_full_name,_maildir,_user,_domain,_quota_bytes,'{"force_pw_update": "0", "tls_enforce_in": "0", "tls_enforce_out": "0"}')
ON DUPLICATE KEY UPDATE username = _email;
-- alias
INSERT INTO alias(address,goto,domain)
VALUES (_email,_email,_domain)
ON DUPLICATE KEY UPDATE address = _email;
-- quota2
INSERT INTO quota2(username,bytes,messages)
VALUES (_email,0,0)
ON DUPLICATE KEY UPDATE username = _email;
-- user_acl
INSERT INTO user_acl(username)
VALUES (_email)
ON DUPLICATE KEY UPDATE username = _email;
END$$
DELIMITER ;
DELIMITER $$
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
ERROR 1136 (21S01) at line 126: Column count doesn't match value count at row 1
When I run the command to restore the SQL backup, I get an error:
ERROR 1136 (21S01) at line 126: Column count doesn't match value count at row 1
In case anyone else misses it, here's a link to the API:
https://mailcow.docs.apiary.io/#reference/mailboxes/create-mailbox
Most helpful comment
Everything exits. I just haven’t enabled it yet. Stupid docs. :-)