Aliases file Migration

This script will parse a sendmail style aliases file including any aliases that are in an ":include:" directive. If you have appropriate comments in the included file they will be placed in the LDAP attributes of the distribution list object.

#!/usr/bin/perl
################################################################################
# $Id: aliases2zmprov,v 1.4 2007/03/07 22:18:56 dlbewley Exp $
#-------------------------------------------------------------------------------
# Description:
#   Tool to create commands suitable for zmprov from a unix aliases file.
#
#   Handles the case of an :include: construct.
#   - Comments in include file are parsed as follows
#   - "Foo" goes in LDAP description attribute, "Bar" in the displayname.
#     # Description: foo
#     # Name: Bar
#
#   Handles the case of remote and multiple recipients by making a dist list.
#   - A Zimbra alias must be associated with exactly one Zimbra account.
#   - A Zimbra distribution list may contain users on remote hosts.
#
# See Also:
#   http://wiki.zimbra.com/index.php?title=Bulk_Create
#
# Usage:
#    ./aliases2zmprov /etc/aliases 1> aliases.zmp 2> aliases.err
#    zmprov < aliases.zmp
#
################################################################################

my @CNAME_SKIP= qw( ftp news postmaster root webmaster );
my @ALIAS_SKIP= qw( abuse mailer-daemon postmaster  );
my @DISTRIBUTION_LISTS;
my $DOMAIN = 'foo.bar.com';
my $SOURCE_HOST = 'mail';

use File::Basename;

while(<>) {
    chomp;
    s/#.*$//; # skip comments
    next if /^\s*$/; # skip blank lines

    my ($description,$display_name,@cnames);
    my ($alias,$cname) = split(/:/,$_,2);

    $alias =~ s/\s*//g;
    # scrutinize the aliases
    if (grep /^$alias$/, @ALIAS_SKIP) {
        warn "skipping alias $alias -> $cname";
        next;
	}

    $cname =~ s/\s*//g; # remove all spaces

    # scrutinize the canonical names
    if ($cname =~ m/:include:/) {
        (($description, $display_name, $cnames_ref) = parse_include($cname)) || next;
        @cnames = @{$cnames_ref};
    }
    if ($cname =~ m/,/) {
        # multiple recipients make this a list instead of an alias
        @cnames = split(/,/,$cname);
    }

    # if more than one cname then it is a dist list
    if (length($cnames[0])) {
        print "\n";
        print "createDistributionList $alias\@$DOMAIN\n";
        push (@DISTRIBUTION_LISTS, $alias);
        if ($display_name) {
            print "modifyDistributionList $alias\@$DOMAIN displayname \"$display_name\"\n";
            $display_name = undef;
        }
        if ($description) {
            print "modifyDistributionList $alias\@$DOMAIN description \"$description\"\n";
            $description = undef;
        }
        foreach my $member (@cnames) {
            # skip aliases to certain users
            if (grep /^$member$/, @CNAME_SKIP) {
                warn "skipping cname $member <- $alias";
                next; # go to next member
            }
            # A Zimbra distribution list may contain users on remote hosts.
            if ($member =~ m/\@/) {
                print "addDistributionListMember $alias\@$DOMAIN $member\n";
            } else {
                print "addDistributionListMember $alias\@$DOMAIN $member\@$DOMAIN\n";
            }
        }
        print "\n";
        @cnames=();
        next; # go to next line of aliases file
    } 

    # skip aliases to certain users
    if (grep /^$cname$/, @CNAME_SKIP) {
        warn "skipping cname $cname <- $alias";
        next;
	}
    if ($cname =~ m/\/|\|/) {
        # alias to a file or a program. don't try to accomodate
        warn "WARNING skipping cname $cname <- $alias it is a file or pipe";
        next;
    }

    # A Zimbra alias must be associated with exactly one Zimbra account.
    if ($cname =~ m/\@/) {
        # alias to remote host. this could be created as a dist list with 1 member
        # that seems undersirable though.
        print "\n";
        print "createDistributionList $alias\@$DOMAIN\n";
        print "addDistributionListMember $alias\@$DOMAIN $cname\n";
        print "\n";
        next; # go to next line of aliases file
    }
    # is the cname a distribution_list already?
    if (grep /^$cname$/, @DISTRIBUTION_LISTS) {
        print "addDistributionListAlias $cname\@$DOMAIN $alias\@$DOMAIN\n";
    }
    # are we sure that account $cname\@$DOMAIN exists?
    else {
        print "addAccountAlias $cname\@$DOMAIN $alias\@$DOMAIN\n";
    }
}

# read an included alias file. commens with Name: and Description:
# are placed into LDAP attributes for the list
sub parse_include {
    my $cname = shift;
    my @cnames;
    # need to pull in contents of file and make a dist
    # list instead of an alias
    my $fullfile = $cname;
    $fullfile =~ s/:include://;
    my ($file,$path) = fileparse($fullfile);
    if (! -e $file) {
        warn "WARNING skipping $alias -> $cname Please run 'scp $SOURCE_HOST:$fullfile .'";
        return; # go to next line of aliases file
    } else {
        # process include file
        open(F,$file) || warn "Can not read $file";
        while (<F>) {
            chomp;
            (m/#\s*Department:*\s*(.*)/) && ($ou = $1); # can't make use of this in zmprov mdl :(
            if (m/#\s*Description:*\s*(.*)/) {
                $description = $1;
                $description =~ s/"/'/g; # don't blow our command line
            }
            if (m/#\s*Name:*\s*(.*)/) {
                $display_name = $1;
                $display_name =~ s/"/'/g; # don't blow our command line
            }
            s/#.*$//; # skip comments
            next if /^\s*$/; # skip blank lines
            push @cnames, $_;
        }
    }
    return $description, $display_name, \@cnames;
}
# example data
__DATA__
admin: root
dudes: me,you
postmaster: sarah
wsu: :include:/etc/mail/lists/wsu.list
jon.doe: jdoe
  • Tip - Put a comma at the end of the line in the aliases file if you want to make a distribution list with one member instead of an alias! Useful if you plan on adding more members later.


Verified Against: unknown Date Created: 4/28/2009
Article ID: https://wiki.zimbra.com/index.php?title=Aliases_file_Migration Date Modified: 2015-03-24



Try Zimbra

Try Zimbra Collaboration with a 60-day free trial.
Get it now »

Want to get involved?

You can contribute in the Community, Wiki, Code, or development of Zimlets.
Find out more. »

Looking for a Video?

Visit our YouTube channel to get the latest webinars, technology news, product overviews, and so much more.
Go to the YouTube channel »

Jump to: navigation, search