[ZIMBRA] Prevent User Customizing “FROM” header


Some of our Zimbra customers are complaining for authenticated user can customizing FROM header which can lead to fraud email. this issue can be reproduce by using thunderbird once compose an email as following picture.


or by using this script, change variables username, password, fake_from and to_addr based on your environment.



I created customized milter engine using python milter library for my workaroud with following features:

Continue reading “[ZIMBRA] Prevent User Customizing “FROM” header”


[Zimbra] Sender Restriction to Distribution List

Distribution list in Zimbra is a mail grouping that makes broadcast mail much easier, but in some corporation there is restriction for limiting only for such user that can send mail to distribution list. If you are using zimbra Network Edition you may just using Zimbra Admin Console but CLI still best friend for those who using OSE 🙂 .

Grant user access for account omar@mymail.ok to send to such distribution list

zmprov grr dl distme@mymail.ok usr admin@mymail.ok sendToDistList

Revoking user access.

zmprov rvr dl distme@mymail.ok usr omar@jmymail.ok sendToDistList

Get access list (grants) to distribution list called distme@mymail.ok

zmprov gg -t dl distme@mymail.ok


  • You must activate Zimbra Milter Service for using this service.
  • i just using grantee-type usr (user) in this example, you may change to another grantee-type if you want to (grp, egp, all, dom, edom, gst, key, pub, email).
  • In every time the rights is changed you must reload mta service by run command zmmtact reload

Create 7zip Archive File With High Compression On Centos

Install 7zip on Centos if it not installed (requiring EPEL repo).

[ root@ centos ~ ]# yum install p7zip

Here’s the command for create high compression 7zip file.

[ root@centos ~ ]# 7za a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on zimbralog.7z /var/log/zimbra.log

Argument explanation:

  • -t7z   7z archive
  • -m0=lzma lzma method
  • -mx=9 level of compression = 9 (Ultra)
  • -mfb=64 number of fast bytes for LZMA = 64
  • -md=32m dictionary size = 32 megabytes
  • -ms=on solid archive = on

Django Custom Authentication

Sometime user authentication not always looked up through database, such in my case for authentication through all user that exists in an email server (zimbra) with goals as below:

1. When username admin or auditor then do normal authentication to database.
2. Other than admin and auditor, authentication against IMAP server.
3. Due all user that logged in must be exist in django database the check to django user database so there will be auto user creation if user not exists.

so here are the steps:

1. Modify your django apps setting, then add custom authentication code. i will put in file namely auth on app jssp.

$ vim settings.py

2. Here are the code to achieve my goals:

from imaplib import IMAP4_SSL
from django.contrib.auth.models import User
from django.conf import settings
from django.contrib.auth.backends import ModelBackend

class CustAuth(ModelBackend):

    def authenticate(self, username=None, password=None):
        # special user admin and auditor will be authenticate to database
        if username == 'admin' or username == 'auditor':
            return ModelBackend.authenticate(self, username=username, password=password)

            # IMAP server configuration implant in django configuration with name IMAP_HOST
            c = IMAP4_SSL(settings.IMAP_HOST)
            c.login(username, password)
            # if IMAP login was failed then just return None as mark of failed authentication on django side
            return None

        # all authentication process must return User object, 
        # try to get one base on username if doesn't exist then create it on the fly
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            user = User.objects.create_user(username, password=password)

        return user

Just modified the code if you have another custom authentication scenario, Enjoy 🙂

Zimlet, add attachment option

This is an example adding attachment option with name Sisipan

 SomeOtherZimlet.prototype.init = function(){



SomeOtherZimlet.prototype.addAttachmentOption = function(){

     this._msgController = AjxDispatcher.run("GetMsgController");
     var viewType = appCtxt.getViewTypeFromId(ZmId.VIEW_MSG);

     // apply this option to all attachment type 
     for ( var mimeType in ZmMimeTable._table) {
           this._msgController._listView[viewType].addAttachmentLinkHandler(mimeType, "simpanan", this.generateAttOption);


// Callback function for generating attachment link button 
SomeOtherZimlet.prototype.generateAttOption = function(attachment){

  var html= "<a href='#' onClick='alert(\""+attachment.label+", This Attachment Located At: "+attachment.url+" \")'>Simpanan</a>";

  return html;

Here the result when an email has attachment and Simpanan link button is clicked


Zimlet base class

Base of zimlet plugin must extend from class ZmZimletBase, and the initialization method  that will be executed every Zimbra Webmail Loaded is init. here some example

function SomeOtherZimlet () {}

SomeOtherZimlet.prototype = new ZmZimletBase();

SomeOtherZimlet.prototype.constructor = SomeOtherZimlet;

SomeOtherZimlet.prototype.init = function(){

     console.log("[SomeOtherZimlet] LOADED");


If you open web development console then you will have an output message [SomeOtherZimlet] LOADED.


These are the best practice to learn creating zimlet:

  • See the unsorted tutorial at Zimbra Wiki Page
  • Reading deployed zimlet that exist at /opt/zimbra/zimlets-deployed
  • If you don’t have zimbra at your environment test, you can see it online at mirror of zimbra repository at github
  • Learning how other or customized zimlet at Zimlet Gallery but the challenge is some or much of zimlet for zimbra 6/7 doesn’t work in zimbra latest version so you must hold tightly at Zimlet Api Documentation