1

Topic: Migration from qmail+vpopmail to iredmail

==== Provide basic information to help troubleshoot ====
- iRedMail version: 0.7.3
- Linux/BSD distribution name and version: Ubuntu server 10.04.1
- Any related log? Log is helpful for troubleshooting.
====

Hi!

I'm trying to find the quickest route to migrate from existing qmail+vpopmail server to different server on Ubuntu server 10.04 LTS and iRedMail 0.7.3 opensource installation with LDAP backend.

Is there a way to transfer mail accounts from on to another? Maybe using vpasswd file in mailbox directory under domain directories?

It doesn't need to be complete transfer including existing passwords but only a way to create exisitng users in bulk under right domain and using this maildir structure:
<path_to_maildir>/<domain>/<user.name>


Thanks in advance!

----

Spider Email Archiver: On-Premises, lightweight email archiving software developed by iRedMail team. Supports Amazon S3 compatible storage and custom branding.

2

Re: Migration from qmail+vpopmail to iredmail

mmesh wrote:

It doesn't need to be complete transfer including existing passwords but only a way to create exisitng users in bulk under right domain and using this maildir structure:
<path_to_maildir>/<domain>/<user.name>

Please refer to script tools "create_mail_user_*" here:
http://code.google.com/p/iredmail/sourc … il%2Ftools

They're shipped in iRedMail-0.7.3 too.

3

Re: Migration from qmail+vpopmail to iredmail

Hi,

I do a lot qmail 2 iRedmail migrations. I use this 2 script. I know, the script are not beautiful, but the do the job for me.

To export most account information in to a ldif.

#!/usr/bin/python2.6
# encoding: utf-8

import shlex, subprocess, sys, re

Domain2Export = ['domain1.com','domain2.com']
LDAPDC = "dc=example,dc=com"


VPOPBASE='/home/vpopmail/bin/'
cmd_vdominfo = "%s/vdominfo "%(VPOPBASE)
cmd_vuserinfo = "%s/vuserinfo "%(VPOPBASE)
cmd_valias = "%s/valias "%(VPOPBASE)

# regex
reDomain = re.compile("^domain")

dictDomains = {}


# get al domains and aliases
pvdominfo = subprocess.Popen(cmd_vdominfo, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in pvdominfo.stdout.readlines():
        line = line.decode("ascii").strip()
        # proccess domain aliases
        if reDomain.match(line):
                reg = re.findall('([a-z0-9-.]+\.[a-z]{2,4})',line) # get al domain names
                if len(reg) == 2:  # 2 domain names, so this is a alias
                        alias = reg[0]
                        domain = reg[1]
                        dictDomains[domain]['domainaliases'].append(alias)
                elif len(reg) == 1:
                        domain = reg[0]
                        dictDomains[domain] = {'domainaliases': [], 'users':{},'mailaliases':[]}
                else:
                        # write line to log file, 
                        continue
        else:
                # write line to log file, 
                continue



        #proccess users from domain
        pvuserinfo_domain = subprocess.Popen("%s -n -D %s"%(cmd_vuserinfo,domain), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        for user in pvuserinfo_domain.stdout.readlines():
                user = user.decode("ascii",'ignore').strip()
                pvuserinfo = subprocess.Popen("%s %s@%s"%(cmd_vuserinfo,user,domain), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
                dictDomains[domain]['users'][user]= {}
                # proccess user info
                for userinfo in pvuserinfo.stdout.readlines():
                        userinfo = userinfo.decode('ascii','ignore')
                       userinfo = userinfo.split(":")
                        dictDomains[domain]['users'][user][userinfo[0]] = userinfo[1].strip() # merge userinfo with global dict.
                        retval_user = pvuserinfo.wait()

        if len(dictDomains[domain]['mailaliases']) == 0:
                pvalias = subprocess.Popen("%s -s %s"%(cmd_valias,domain), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
                for alias in pvalias.stdout.readlines():
                        alias = alias.decode('ascii').strip().split(' -> ')
                        dictDomains[domain]['mailaliases'].append(alias)
                        retval_alias = pvalias.wait()

                retval = pvdominfo.wait()




# Create LDIF
for domain in dictDomains:
        if domain not in Domain2Export:
                continue


        print """dn: domainName=%s,o=domains,%s
accountstatus: active
domainname: %s
enabledservice: mail
enabledservice: senderbcc
enabledservice: recipientbcc
mtatransport: dovecot
objectclass: mailDomain

dn: ou=Aliases,domainName=%s,o=domains,%s
objectclass: organizationalUnit
objectclass: top
ou: Aliases

dn: ou=Externals,domainName=%s,o=domains,%s
objectclass: organizationalUnit
objectclass: top
ou: Externals

dn: ou=Groups,domainName=%s,o=domains,%s
objectclass: organizationalUnit
objectclass: top
ou: Groups

dn: ou=Users,domainName=%s,o=domains,%s
objectclass: organizationalUnit
objectclass: top
ou: Users

"""%(domain,LDAPDC, domain,domain,LDAPDC,domain,LDAPDC,domain,LDAPDC,domain,LDAPDC)
        if len(dictDomains[domain]['domainaliases']) > 0:
                print "changetype: modify"
                print "add: enabledservice"
                print "enabledservice: domainalias"
                print ""
                for alias in dictDomains[domain]['domainaliases']:
                        print "dn: domainName=%s,o=domains,%s"%(domain,LDAPDC)
                        print "changetype: modify"
                        print "add: domainaliasname"
                        print "domainaliasname: %s"%(alias)
                        print ""


        for user in dictDomains[domain]['users']:
                userinfo = dictDomains[domain]['users'][user]
                print """dn: mail=%s@%s,ou=Users,domainName=%s,o=domains,%s
changetype: add
objectClass: inetOrgPerson
objectClass: mailUser
objectClass: shadowAccount
objectClass: amavisAccount
mail: %s@%s
userPassword: %s
mailQuota: %s
cn: %s
sn: %s
uid: %s@%s
storageBaseDirectory: /var/vmail/vmail1
mailMessageStore: vmail1/%s/%s/
homeDirectory: /var/vmail/vmail1/%s/%s/
accountStatus: active
mtaTransport: dovecot
enabledService: mail
enabledService: smtp
enabledService: smtpsecured
enabledService: pop3
enabledService: pop3secured
enabledService: imap
enabledService: imapsecured
enabledService: deliver
enabledService: forward
enabledService: senderbcc
enabledService: recipientbcc
enabledService: managesieve
enabledService: managesievesecured
enabledService: internal
enabledService: sieve
enabledService: sievesecured
enabledService: shadowaddress
enabledService: displayedInGlobalAddressBook
"""%(userinfo['name'],domain,domain,LDAPDC,userinfo['name'],domain,userinfo['clear passwd'],"3221225472",userinfo['name'],userinfo['name'],userinfo['name'],domain,domain,userinfo['name'],domain,userinfo['name'])


        for alias in dictDomains[domain]['mailaliases']:
                match = re.search(r'^&.*', alias[1])
                if match:
                        toemail = re.sub(r'^&',r'',alias[1])
                        toemail = re.sub(r'\.nl$',r'.net',toemail)
                        fromalias = alias[0]
                        print """dn: mail=%s,ou=Users,domainName=%s,o=domains,%s
changetype: modify
add: shadowaddress
shadowaddress: %s """%(toemail,domain,LDAPDC,fromalias)
                        print ""
"""
for domain in dictDomains:
        if domain not in Domain2Export:
                continue

        for alias in dictDomains[domain]['domainaliases']:
                print ("    DomainAlias %s"%(alias))

        for alias in dictDomains[domain]['mailaliases']:
                print ("    MailAlias %s"%(alias))


        for user in dictDomains[domain]['users']:
                print ("    User %s@%s"%(user,domain))
                for userinfo in dictDomains[domain]['users'][user]:
                        print ("             %s : %s"%(userinfo,dictDomains[domain]['users'][user][userinfo]))
                        


"""

Because qmail puts forwards in .qmail file

#!/bin/bash
DC="dc=example,dc=net"
for x in $(find /home/vpopmail/domains/ -type f -name ".qmail")
do
       domain=$(echo $x | awk -F '/' '{print $5;}')
       email=$(echo $x | awk -F '/' '{print $6"@"$5;}')
       for f in $(grep ^\& $x)
       do
               if [ ! -z $f ]; then
                       echo "dn: mail=$email,ou=Users,domainName=$domain,o=domains,$DC"
                       echo "changetype: modify"
                       echo "add: mailForwardingAddress"
                       echo "mailForwardingAddress: $(echo $f|sed 's/^&//')"
                       echo
               fi
       done
done

I hope, this will help some ppl.

4

Re: Migration from qmail+vpopmail to iredmail

Hi @wica,

Thanks very much for your sharing. smile

5

Re: Migration from qmail+vpopmail to iredmail

Hi wica,
Your post interests me as we have about 3-4 domains on a qmail + vpopmail (qmailrocks) setup. No mysql and ldap for the qmail.

While you have given two scripts, would appreciate more on usage of the same and details on whether they are for every domain separately or all domains at once.

From there, how do we convert it for iRedMail.

Based on the success of this, intending to buy the iRedMail Pro license. So, hope you can reply at the earliest.

Vasanth

wica wrote:

Hi,

I do a lot qmail 2 iRedmail migrations. I use this 2 script. I know, the script are not beautiful, but the do the job for me.

To export most account information in to a ldif.

#!/usr/bin/python2.6
# encoding: utf-8

import shlex, subprocess, sys, re

Domain2Export = ['domain1.com','domain2.com']
LDAPDC = "dc=example,dc=com"


VPOPBASE='/home/vpopmail/bin/'
cmd_vdominfo = "%s/vdominfo "%(VPOPBASE)
cmd_vuserinfo = "%s/vuserinfo "%(VPOPBASE)
cmd_valias = "%s/valias "%(VPOPBASE)

# regex
reDomain = re.compile("^domain")

dictDomains = {}


# get al domains and aliases
pvdominfo = subprocess.Popen(cmd_vdominfo, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in pvdominfo.stdout.readlines():
        line = line.decode("ascii").strip()
        # proccess domain aliases
        if reDomain.match(line):
                reg = re.findall('([a-z0-9-.]+\.[a-z]{2,4})',line) # get al domain names
                if len(reg) == 2:  # 2 domain names, so this is a alias
                        alias = reg[0]
                        domain = reg[1]
                        dictDomains[domain]['domainaliases'].append(alias)
                elif len(reg) == 1:
                        domain = reg[0]
                        dictDomains[domain] = {'domainaliases': [], 'users':{},'mailaliases':[]}
                else:
                        # write line to log file, 
                        continue
        else:
                # write line to log file, 
                continue



        #proccess users from domain
        pvuserinfo_domain = subprocess.Popen("%s -n -D %s"%(cmd_vuserinfo,domain), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        for user in pvuserinfo_domain.stdout.readlines():
                user = user.decode("ascii",'ignore').strip()
                pvuserinfo = subprocess.Popen("%s %s@%s"%(cmd_vuserinfo,user,domain), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
                dictDomains[domain]['users'][user]= {}
                # proccess user info
                for userinfo in pvuserinfo.stdout.readlines():
                        userinfo = userinfo.decode('ascii','ignore')
                       userinfo = userinfo.split(":")
                        dictDomains[domain]['users'][user][userinfo[0]] = userinfo[1].strip() # merge userinfo with global dict.
                        retval_user = pvuserinfo.wait()

        if len(dictDomains[domain]['mailaliases']) == 0:
                pvalias = subprocess.Popen("%s -s %s"%(cmd_valias,domain), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
                for alias in pvalias.stdout.readlines():
                        alias = alias.decode('ascii').strip().split(' -> ')
                        dictDomains[domain]['mailaliases'].append(alias)
                        retval_alias = pvalias.wait()

                retval = pvdominfo.wait()




# Create LDIF
for domain in dictDomains:
        if domain not in Domain2Export:
                continue


        print """dn: domainName=%s,o=domains,%s
accountstatus: active
domainname: %s
enabledservice: mail
enabledservice: senderbcc
enabledservice: recipientbcc
mtatransport: dovecot
objectclass: mailDomain

dn: ou=Aliases,domainName=%s,o=domains,%s
objectclass: organizationalUnit
objectclass: top
ou: Aliases

dn: ou=Externals,domainName=%s,o=domains,%s
objectclass: organizationalUnit
objectclass: top
ou: Externals

dn: ou=Groups,domainName=%s,o=domains,%s
objectclass: organizationalUnit
objectclass: top
ou: Groups

dn: ou=Users,domainName=%s,o=domains,%s
objectclass: organizationalUnit
objectclass: top
ou: Users

"""%(domain,LDAPDC, domain,domain,LDAPDC,domain,LDAPDC,domain,LDAPDC,domain,LDAPDC)
        if len(dictDomains[domain]['domainaliases']) > 0:
                print "changetype: modify"
                print "add: enabledservice"
                print "enabledservice: domainalias"
                print ""
                for alias in dictDomains[domain]['domainaliases']:
                        print "dn: domainName=%s,o=domains,%s"%(domain,LDAPDC)
                        print "changetype: modify"
                        print "add: domainaliasname"
                        print "domainaliasname: %s"%(alias)
                        print ""


        for user in dictDomains[domain]['users']:
                userinfo = dictDomains[domain]['users'][user]
                print """dn: mail=%s@%s,ou=Users,domainName=%s,o=domains,%s
changetype: add
objectClass: inetOrgPerson
objectClass: mailUser
objectClass: shadowAccount
objectClass: amavisAccount
mail: %s@%s
userPassword: %s
mailQuota: %s
cn: %s
sn: %s
uid: %s@%s
storageBaseDirectory: /var/vmail/vmail1
mailMessageStore: vmail1/%s/%s/
homeDirectory: /var/vmail/vmail1/%s/%s/
accountStatus: active
mtaTransport: dovecot
enabledService: mail
enabledService: smtp
enabledService: smtpsecured
enabledService: pop3
enabledService: pop3secured
enabledService: imap
enabledService: imapsecured
enabledService: deliver
enabledService: forward
enabledService: senderbcc
enabledService: recipientbcc
enabledService: managesieve
enabledService: managesievesecured
enabledService: internal
enabledService: sieve
enabledService: sievesecured
enabledService: shadowaddress
enabledService: displayedInGlobalAddressBook
"""%(userinfo['name'],domain,domain,LDAPDC,userinfo['name'],domain,userinfo['clear passwd'],"3221225472",userinfo['name'],userinfo['name'],userinfo['name'],domain,domain,userinfo['name'],domain,userinfo['name'])


        for alias in dictDomains[domain]['mailaliases']:
                match = re.search(r'^&.*', alias[1])
                if match:
                        toemail = re.sub(r'^&',r'',alias[1])
                        toemail = re.sub(r'\.nl$',r'.net',toemail)
                        fromalias = alias[0]
                        print """dn: mail=%s,ou=Users,domainName=%s,o=domains,%s
changetype: modify
add: shadowaddress
shadowaddress: %s """%(toemail,domain,LDAPDC,fromalias)
                        print ""
"""
for domain in dictDomains:
        if domain not in Domain2Export:
                continue

        for alias in dictDomains[domain]['domainaliases']:
                print ("    DomainAlias %s"%(alias))

        for alias in dictDomains[domain]['mailaliases']:
                print ("    MailAlias %s"%(alias))


        for user in dictDomains[domain]['users']:
                print ("    User %s@%s"%(user,domain))
                for userinfo in dictDomains[domain]['users'][user]:
                        print ("             %s : %s"%(userinfo,dictDomains[domain]['users'][user][userinfo]))
                        


"""

Because qmail puts forwards in .qmail file

#!/bin/bash
DC="dc=example,dc=net"
for x in $(find /home/vpopmail/domains/ -type f -name ".qmail")
do
       domain=$(echo $x | awk -F '/' '{print $5;}')
       email=$(echo $x | awk -F '/' '{print $6"@"$5;}')
       for f in $(grep ^\& $x)
       do
               if [ ! -z $f ]; then
                       echo "dn: mail=$email,ou=Users,domainName=$domain,o=domains,$DC"
                       echo "changetype: modify"
                       echo "add: mailForwardingAddress"
                       echo "mailForwardingAddress: $(echo $f|sed 's/^&//')"
                       echo
               fi
       done
done

I hope, this will help some ppl.

6

Re: Migration from qmail+vpopmail to iredmail

vasanth wrote:

Hi wica,
Your post interests me as we have about 3-4 domains on a qmail + vpopmail (qmailrocks) setup. No mysql and ldap for the qmail.

While you have given two scripts, would appreciate more on usage of the same and details on whether they are for every domain separately or all domains at once.

From there, how do we convert it for iRedMail.

Based on the success of this, intending to buy the iRedMail Pro license. So, hope you can reply at the earliest.

Vasanth

[q]...[/q]

Hi Vasanth,

That you wanne buy iRedMail Pro license, is nice for ZhangHuangbin smile (@ZhangHuangbin can we do something about this tongue ) I'm used a user smile

But my script can handle more then one domain, Domain2Export = ['domain1.com','domain2.com',....]
It is necessary you know a little about python, to use this scripts.

7

Re: Migration from qmail+vpopmail to iredmail

Hi wica,
Thanks for the quick reply.

Yes, I am not very familiar with python. Those scripts you have posted is throwing an error on line 26.

====
File "./qm-iredmail-ldap-mig.py", line 26
    if reDomain.match(line):
    ^
IndentationError: unexpected indent
=====

8

Re: Migration from qmail+vpopmail to iredmail

====
File "./qm-iredmail-ldap-mig.py", line 26
    if reDomain.match(line):
    ^
IndentationError: unexpected indent

You should keep the same indent level, it's required by Python.

9 (edited by vasanth 2012-05-02 20:55:35)

Re: Migration from qmail+vpopmail to iredmail

Hi Zhang Huangbin,
Nice to see your reply.

Could you pls advise on how to run this script. Does it go with any arguments or parameters?

One more thing is, i only have python 2.5 on this server. hope this is not a big lapse.

Vasanth

ZhangHuangbin wrote:

====
File "./qm-iredmail-ldap-mig.py", line 26
    if reDomain.match(line):
    ^
IndentationError: unexpected indent

You should keep the same indent level, it's required by Python.

10

Re: Migration from qmail+vpopmail to iredmail

Hi Vasanth,

No agruments needed, only some changes in the script.
It is only a export script, so you can test it in producten without data lost.

Grtz, Jiri

vasanth wrote:

Hi Zhang Huangbin,
Nice to see your reply.

Could you pls advise on how to run this script. Does it go with any arguments or parameters?

One more thing is, i only have python 2.5 on this server. hope this is not a big lapse.

Vasanth

ZhangHuangbin wrote:

====
File "./qm-iredmail-ldap-mig.py", line 26
    if reDomain.match(line):
    ^
IndentationError: unexpected indent

You should keep the same indent level, it's required by Python.