Documentary for Dinner: Vice Motherboard: Internet Scamming in Ghana (2013)
Vice travels to Ghana to meet the Sakawa Boys, Internet fraudsters with a mystical twist.
Vice travels to Ghana to meet the Sakawa Boys, Internet fraudsters with a mystical twist.
After dealing with kernel panics (from what I am hoping was merely OOMs) by moving my new Zimbra VM to a different box and giving it 4 cores and 4 gigs of ram and 4 gigs of swap I was about 80 accounts deep into my second Courier-IMAP Maildir Migration when it started throwing this error:
service.FAILURE (system failure: ZimbraLdapContext)
dmesg shows:
[ 1299.261973] slapd[10678]: segfault at 444d2d54 eip b778f154 esp b1587e28 error 4
Upon restarting Zimbra everything seems to be fine. Unfortunately, the one reference to this error I have found (http://wiki.zimbra.com/wiki/Uninstall_Instructions_for_Unix_and_Windows_Account_Management_in_Admin_UI) states:
Once this is done, you're almost out of the woods, but this last step is very, very important. You MUST run slapindex to update the indexes in your Zimbra LDAP database, or you run the risk of having segfault/protection errors that crash the slapd process. So far, this has mostly been observed using Zimbra Network Edition running on Ubuntu 8.04 Server LTS. The exact command is '/opt/zimbra/openldap-2.3.43.10z/sbin/slapindex'. The command will probably throw you an error message about "loglevel". Open the referenced slapd file and temporarily change the log-level to an actual number (49152 is what I usually set it to). Then revert that change after slapindex has run. Start Zimbra again via 'zmcontrol start' and watch the processes for about 30 minutes to make sure nothing is amiss. If you get slapd errors, run slapindex again, it's usually the cause of the problem.
The article has very little to do with what I'm trying to accomplish, but given the versions of Ubuntu and Zimbra I think it's a fair bet that either/and:
Unfortunately, the migration moves quite slowly so adding slapindex to the script is out of the question.
I'll be giving ZCS 8 a shot on RHEL 6 tomorrow. Hooray. >.>
NetworkManager is an annoying network configurator for home users. It will interfere with custom network-scripts unless disabled.
# chkconfig --level 2345 NetworkManager off # /etc/init.d/NetworkManager stop
If your Zimbra server's storage is running out or you try to keep your virtual machines lean and easily transferrable it might be necessary to put Zimbra's mail storage on a different file system or storage medium.
The process is straightforward; they key is knowing that Zimbra stores mail in /opt/zimbra/store.
In my case, I'm creating and attaching a 20 GB sparse file to a virtual machine:
# dd if=/dev/zero of=storage.img seek=20000 bs=1M count=0 # mke2fs -j storage.img
After attaching your storage and creating the file system boot your Zimbra server (if necessary) and mount the file system to /mnt/tmp
# mkdir /mnt/tmp # mount /dev/sda2 /mnt/tmp
Shut down Zimbra if it is running.
# /etc/inid.d/zimbra stop
Change the ownership of the new file system's root directory to your zimbra user:
# chown zimbra: /mnt/tmp
Move the contents of /opt/zimbra/store (or wherever your store directory is located) to /mnt/tmp:
# mv /opt/zimbra/store/* /mnt/tmp/
Unmount /mnt/tmp:
# umount /mnt/tmp
Now create an appropriate fstab entry for /opt/zimbra/store using the new file system's device node/label/etc.:
/dev/sdb1 /opt/zimbra/store ext3 defaults,noatime 0 0
Mount /opt/zimbra/store and start Zimbra:
# mount /opt/zimbra/store # /etc/init.d/zimbra start
I have the good fortune of being forced to migrate over 1,100 e-mail accounts from a 15 year old qmail server with Courier-IMAP.
A script is provided at http://wiki.zimbra.com/wiki/Courier-IMAP_Maildir_to_zmmailbox. It should be easy to run as root and import over NFS. Unfortunately, I ran into trouble with the --noVerify flag, possibly due to the older version of Zimbra I'm importing to:
* Running import process... 0 ...some messages did not import correctly: check /tmp//import-example.com-user--6108
The output of the log looks like:
addMessage --flags "u" --noValidation "/Inbox" "/mnt/example.com/user/Maildir//cur/1362778133.14175.smtp.example.com:2,"
To test it you're going to have to look at the prefix in the script:
/opt/zimbra/bin/zmmailbox -m [email protected] -z addMessage --flags "u" --noValidation "/Inbox" "/mnt/example.com/user/Maildir//cur/1362778133.14175.smtp.example.com:2,"
Which gave me the following error:
ERROR: zclient.CLIENT_ERROR (unknown folder: --noValidation)
I tried putting the --noValidation flag in every position with no luck, and it is listed in the Zimbra wiki article for zmmailbox at http://wiki.zimbra.com/wiki/Zmmailbox so I am left to assume my version simply does not support it. It doesn't seem to be consequential anyway so I simply removed it from the script.
#!/bin/bash # # courier/vpopmail Maildir to Zimbra Import # # This script can be stored anywhere, but you should run it while in the root # of the domain's users. It looks for the file vpasswd which contains a # line-separated list of users and uses that to import. You can also run the # script with a user name to process a single user. Additionally, you can # specify a folder name (courier format) to process a single folder for that # user. # We assume the folder structure is like this: # Inbox: <working directory>/<user>/Maildir/<cur|new> # Subfolder: <working directory>/<user>/Maildir/.Subfolder/<cur|new> # If this is not what your structure looks like, you need to change the # "folderpath" variable construction down further in this script. # This is the command to run to run mailbox commands. ZMCMD='/opt/zimbra/bin/zmmailbox -z' # This will be used for temporary/log files during the import process TEMP='/tmp/' # We assume the working directory's name is the domain. # Otherwise, override this with your actual domain name. domain=`basename ${PWD}` echo Process ID: $$ if $1 != "" ; then USERS=$1; else USERS=`cat vpasswd | cut -f1 -d:` fi for user in ${USERS}; do echo "Beginning User: $user..." if $2 != "" ; then FOLDERS="$user/Maildir/$2/cur"; else FOLDERS=`find $user -type d -name cur | sort` fi echo "$FOLDERS" | while read line; do folderdir=`echo ${line} | cut -f3 -d"/"` if ${folderdir} == "cur" ; then folderdir=""; fi folder=`echo ${folderdir} | sed 's/^\.//; s%\.%/%g; s%\&-%\&%g'` folderpath=${PWD}/${user}/Maildir/${folderdir}/ # If the folder name is blank, this is the top level folder, # Zimbra calls it "Inbox" (so do most clients/servers). if $folder == "" ; then folder="Inbox"; fi # In Courier IMAP, all folders must be children of the root # folder, which means Trash, Junk, Sent, Drafts are typically # under Inbox. This is not the case with Zimbra, so we will # slide these mailboxes to the top level so they behave properly, # For all "non-special" mailboxes, we will keep them as children # so they remain where the user had them before. if [[ $folder != "Trash" && $folder != "Junk" && $folder != "Sent" && $folder != "Drafts" && $folder != "Inbox" ]] ; then folder="Inbox/${folder}"; fi echo "* Working on Folder $folder..." # Courier allows heirarchy where non-folders (literally nothing) are # able to have children. Zimbra does not. It's also possible that # we will process the folders out of heirarchical order for some reason # Here we separate the path and make sure all the parent folders exist # before trying to create the folder we're working on. parts=(`echo $folder | sed 's% %\x1a%g; s%/% %g'`); hier=""; for i in "${parts[@]}"; do hier=`echo ${hier}/$i | sed 's%^/%%; s%\x1a% %g'`; ${ZMCMD} -m ${user}@${domain} getFolder "/${hier}" >/dev/null 2>&1 || ( echo -n " + Creating folder $hier... " && ${ZMCMD} -m ${user}@${domain} createFolder "/${hier}" ) done # Figure out how many messages we have count=`find "${folderpath}new/" "${folderpath}cur/" -type f | wc -l`; imported=0; echo " * $count messages to process..." # Define the temporary file names we will need importfn="${TEMP}/import-$domain-$user-$folderdir-$$" implogfn="${TEMP}/import-$domain-$user-$folderdir-$$-log" impflogfn="${TEMP}/import-$domain-$user-$folderdir-$$-flaglog" impflagfn="${TEMP}/import-$domain-$user-$folderdir-$$-flags" touch "$importfn" # Determine the courier extended flag identifiers ("keywords") flagid=0 if -f "${folderpath}courierimapkeywords/:list" ; then extflags="YES" cat "${folderpath}courierimapkeywords/:list" 2>/dev/null | while read line; do # A blank line indicates the end of the definitions. if "${line}" == "" ; then break; fi # To avoid escape character madness, I'm swapping $ with % here. flag=`echo ${line} | sed 's/\\\$/%/'` echo courierflag[${flagid}]="'$flag'"; flagid=$(( flagid + 1 )); # Create the tag if it doesn't start with '%' if `echo ${flag} | grep '%'` == "" ; then echo -n " + Attemping to create tag ${flag}... " >&2 ${ZMCMD} -m ${user}@${domain} createTag "${flag}" >&2 fi done > "$impflagfn" source "$impflagfn" fi echo -n " * Queuing messages for import... " # Find all "cur" or "new" messages in this folder and import them. find "${folderpath}new/" "${folderpath}cur/" -type f | while read msg; do flags=""; tags=""; msgid=`echo $msg | cut -d: -f1 | sed s%.*/%%` # Determine the old maildir style flags oldflags=`echo $msg | cut -d: -f2` # Replied if `echo ${oldflags} | grep 'R'` != "" ; then flags="${flags}r"; fi # Seen if `echo ${oldflags} | grep 'S'` == "" ; then flags="${flags}u"; fi # Trashed if `echo ${oldflags} | grep 'T'` != "" ; then flags="${flags}x"; fi # Draft if `echo ${oldflags} | grep 'D'` != "" ; then flags="${flags}d"; fi # Flagged if `echo ${oldflags} | grep 'F'` != "" ; then flags="${flags}f"; fi # Determine the courier-imap extended flags for this message if ${extflags} == "YES" ; then oldflags2=`grep $msgid "${folderpath}courierimapkeywords/:list" 2>/dev/null | cut -d: -f2` for flag in ${oldflags2}; do # Forwarded if ${courierflag[$flag]} == '%Forwarded' ; then flags="${flags}w"; fi # Sent by me if ${courierflag[$flag]} == '%MDNSent' ; then flags="${flags}s"; fi # Convert non-system flags to Zimbra tags if `echo ${courierflag[$flag]} | grep '%'` == "" ; then tags="${tags},${courierflag[$flag]}" fi done # Clean up the tag list for the command line if ${tags} != "" ; then tags=`echo ${tags} | sed "s/^,\?/--tags \'/; s/\$/\'/"`; fi fi # Log the result of flag processing for debugging if $flags != "" || $tags != "" ; then echo `date +%c` "$msg had flags $oldflags and $oldflags2, now $flags and $tags in folder $folder" >> "$impflogfn" fi # Add the command to the queue file to import this message echo "addMessage --flags \"${flags}\" ${tags} \"/$folder\" \"${msg}\"" >> "$importfn" imported=$(( $imported + 1 )); printf "\b\b\b\b\b\b\b\b%7d " $imported; done echo "...done"; # Since we redirect the queue file to the mailbox tool, we end with "quit" echo "quit" >> "$importfn" # We're counting "prompts" from the zmmailbox utility here. The first # one comes up before a message is imported, so we start at -1 to offset # its existence. imported=-1; # We do this redirect because running the command for each message is very # slow. We can't just pass the directory to the command, despite Zimbra's # support because we can't tag or flag the messages that way. echo -n " * Running import process... " ${ZMCMD} -m $user@$domain < "${importfn}" 2> "${implogfn}" | while read; do imported=$(( $imported + 1 )); printf "\b\b\b\b\b\b\b\b%7d " $imported; done if -s "${implogfn}" ; then echo "...some messages did not import correctly: check $importfn"; else echo "...done"; fi done done echo "Import Process Complete!"
Now my output for a single account is:
Process ID: 11495 Beginning User: user... * Working on Folder Inbox/Archive... + Creating folder Inbox/Archive... 285 * 0 messages to process... * Queuing messages for import... ...done * Running import process... 0 ...done * Working on Folder Drafts... * 0 messages to process... * Queuing messages for import... ...done * Running import process... 0 ...done * Working on Folder Junk... * 0 messages to process... * Queuing messages for import... ...done * Running import process... 0 ...done * Working on Folder Sent... * 3 messages to process... * Queuing messages for import... 3 ...done * Running import process... 3 ...done * Working on Folder Trash... * 0 messages to process... * Queuing messages for import... ...done * Running import process... 0 ...done * Working on Folder Inbox/new folder... + Creating folder Inbox/new folder... 289 * 5 messages to process... * Queuing messages for import... 5 ...done * Running import process... 5 ...done * Working on Folder Inbox... * 1 messages to process... * Queuing messages for import... 1 ...done * Running import process... 1 ...done Import Process Complete!
It is important to note that running the import script multiple times will result in the e-mails being imported multiple times and it takes a fair amount of time to perform this procedure on one account nevermind one thousand so a strategy should be formulated for dealing with runoff mail before the MX/target is switched.