SlideShare uma empresa Scribd logo
1 de 114
Posts: 138

LHammonds
Special Member
My Notes for Installing Zimbra OSE on Ubuntu Server 10.04 LTS
Greetings and salutations,

I hope this thread will be helpful to those who follow in my foot steps as well as getting
any advice based on what I have done / documented. I am a documentation freak so this
will probably grow into a very LARGE step-by-step process. If useful, it will probably be
best to convert to a wiki once completed.
This is a Work-In-Progress topic so I will be updating this thread as I go through this
transition from MS Exchange to Zimbra.

High-level overview
This thread will cover installation of Ubuntu server inside a virtual machine vSphere 4.1
running on ESXi 4.1 servers. Although there is some VMware-specific steps, they are very
few and the majority of this documentation will work for other VMs such as VirtualBox or
even directly installed onto a physical machine. It will also cover the installation and
configuration of Zimbra OSE and the Zimbra desktop client. This is a merge of several
other guides, comments and my own experience of putting it all together in one place in a
format that is easy for me to follow and reproduce the same results (yes, I create
documentation that I will have to re-read one day because of my bad memory problems!).
Please excuse my ignorance since I am fairly new to Linux and Zimbra...if you have any
advice on doing things better, please let me know. I love feedback and learning better ways
of doing things!

Company background and environment
I have finished evaluating different mail options for my company and we decided to make
the switch to Zimbra. We are a small shop of about 200 employees and are currently using
Microsoft Exchange 2003 on a physical server.
We are going to switch from Exchange to Zimbra. We are not fully utilizing Exchange
features and are mainly using it for email, contacts, calendars and shared calendars (for
scheduling meeting rooms). We use Active Directory (Windows 2003 domain) to manage
users and distribution lists. The desktops are mainly Windows XP and some newer boxes
are coming in with Windows 7. We are using Microsoft Outlook with personal folders
since we have mailbox size restrictions of 200 MB per mailbox as well as the web interface
for people that constantly move from desk-to-desk. iPhones and iPads are also being used
as portable devices.
The email server will be sitting behind a firewall on our LAN. Here is a graphic
representation of the network layout:
About the IT staff
We are primarily a Microsoft shop and as such, most of us (3) have Microsoft certifications
such as MCSE, MCDBA and MCP. None of us are Unix administrators but we are fairly
competent in the use of the system from having to support an AIX server so we are
comfortable in the VI editor but know very little in terms of Unix hardware and software
administration (just basic user stuff, enough to be dangerous)

The deployment process
Here are the high-level milestones for this project.
Phase 1 - Setup a fully-functional system for testing, training and migration.
Phase 2 - Create Backup / Restore process and documentation
Phase 3 - Install client software on all devices
Phase 4 - Create and deploy training materials (web docs / videos)
Phase 5 - Migrate users (over a weekend)
Phase 6 - Decommission old system (with a flamethrower)

Tools utilized in this process
Ubuntu Server 10.04 LTS, 64-bit
Zimbra OSE 7.2.0, 64-bit
Zimbra Desktop Client 7.1.4
Portable PuTTY 0.62
VMware vSphere 4.1.0

Helpful links
The list below are sources of information that helped me configure this system as well as
some places that might be helpful to me later on as this process continues.
Ubuntu Documentation
Zimbra Network Edition Documentation (PDF files)
Zimbra Open Source Edition Documentation (PDF files)
Zimbra Desktop User Guide
Ubuntu Firewall Basics
Firewall Configuration for Zimbra
Ubuntu AppArmor Basics
Ubuntu 8 and Zimbra Install Guide
Making Zimbra and BIND Work Together
Split DNS Guide
Z-Push (Over-The-Air ActiveSync)
Funambol (Over-The-Air iPhone contact sync)
djigzo (email encryption @ the gateway)
Mondo Rescue (Ubuntu OS backup)
MailArchiva (email Journaling and archival)
TurnKeyLinux Zimbra Appliance (fast-n-easy to get running even if you are 100%
unfamiliar with Linux/Zimbra)
ZeXtras Migration Tool (upgrade OS or change from dedicated to multi-domain
server)
Location of Zimbra Log Files
Zimbra Online Quote Tool
Assumptions
This documentation will need to make use of some very-specific information that will
most-likely be different for each person / location. And as such, I will note some of these in
this section. They will be highlighted in red throughout the document as a reminder that
you should plug-in your own value rather than actually using my "place-holder" value.
Under no circumstance should you use that actual values I list below. They are placeholders for the real thing. This is just a checklist template you need to have answered
before you start the install process.
Wherever you see RED in this document, you need to substitute it for what your company
uses. Use the list below as a template you need to have answered before you continue.
Ubuntu Server name: mail
Internet domain: mydomain.com
Server domain alias (Windows): work
Server fully-qualified windows domain: work.mydomain.com
Ubuntu Server IP address: 192.168.107.25 (my attempt at geek humor...raise your
hand if you get it)
Ubuntu Server IP subnet mask: 255.255.255.0
Ubuntu Server IP gateway: 192.168.107.1
Internal DNS Server 1: 192.168.107.23
Internal DNS Server 2: 192.168.107.212
Internal Active Directory: 192.168.107.212
External ISP DNS Server 1: 200.100.10.1
External ISP DNS Server 2: 200.100.10.2
External IP to Domain: 198.100.100.100
Ubuntu Admin ID: administrator
Ubuntu Admin Password: myadminpass
Ubuntu Root Password: myrootpass
Zimbra Admin Password: myzimbrapass

I also assume the reader knows how to use the VI editor. If not, you will need to beef up
your skill set or use a different editor in place of it.
__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
Last edited by LHammonds; 05-07-2012 at 03:03 PM..
#2 (permalink)
04-26-2012, 07:07 PM
LHammonds
Special Member

Posts: 138
Analysis and Design

Analysis and Design
The user base will probably not exceed 300 any time soon based on the company size over
the last 80 years.
A single server design is chosen for this deployement based on the amount of current users
(~200)
The Ubuntu Server Long-Term Support (LTS) is free but we have the option of buy support
and that is the main reason this server was selected.
Zimbra OSE is also free but we have the option of buying support by upgrading to the
Network Edition.
The Ubuntu LTS / Zimbra OSE combination makes for an excellent choice to evaluate the
products (without incurring licensing fees) as well as having an upgrade path to obtain
support.
Much of how the system will run is based on how you install / configure Ubuntu before you
ever install Zimbra.
The largest decision over the configuration of Ubuntu seems to be how the hard drive space
is sliced up (partitioned). I lot of my time was spent researching and learning the various
options when it comes to the design layout of the storage.
The Zimbra documentation's recommendation for Ubuntu in this area basically says to put
everything on one LVM/Volume. I can see how tech support would want to favor a setup
like this because it makes it easier to troubleshoot. However, I would rather make use of a
design that allows for dynamic growth and fine-tuning if need be. I also do not like being
caught offguard with a scenario where space is filled up with no immediate option other
than deleting files. Long-term life and growth of the system as well as budgeting concerns
have to be taken into consideration.
Based on my observations during the first Zimbra install, I decided that a single volume
wasn't a good idea, especially having continual-growth of a folder that is on the root
volume. I would rather contain the root volume to mainly just static data that won't grow
much and push the other folders that are dynamic into their own volumes. In case you don't
know, filling up the root volume on a *nix system is a very bad thing and should be avoided
at all costs. I also want to configure it where the file systems are not taking up 100% of the
logical volume. This will allow me (through automated scripts) to grow the file system as
needed and give me some time to add more drives if necessary or shrink other volumes to
get more space.
Here are my thoughts on how to slice up the space.
Boot - This will remain static in size. It is also the only space residing outside the
Logical Volume Manager (LVM)
Root volume - Operating system and everything else which should remain fairly
static.
Swap volume - This will remain static in size. However, if amount of RAM is
adjusted, this should be adjusted as well.
Opt volume - This Zimbra storage will continue to grow over time.
Backup volume - This will contain a local backup of the Opt volume and
individually compressed mailbox archives. So space needs to be around double
/opt/zimbra.
Temp volume - This location will be used to hold data during backups, archives
and restores and should be about double the size of opt/zimbra.
Offsite Storage - This will be handled elsewhere but will be mounted on this server.
My estimated mailbox store will be about 25 GB. However, we will start this server off
with a much lower number. We will then pretend some event happened such as acquiring
an additional company / employees. This will increase our storage needs and we will go
through adjusting the entire system to accommodate a larger storage capacity. This will be a
good exercise / documentation for what will eventually need to be done later to handle
growth.
To get a good idea of the hard drive layout and to understand the process better, here is a
graphical representation of the initial design for the server:
These numbers will be used for the initial build of the system:
boot = 200 MB
root = 4 GB
swap = 8 GB
opt = 10 GB
temp = 20 GB
backup = 20 GB

Virtual Machine Settings
Virtual Manager: VMware vSphere Client 4.1
Virtual Host: VMware ESXi Server 4.1
Configuration: Custom
Name: ZimbraMail
Datastore: MainOffice-LUN0
Virtual Machine Version: 7
Guest Operating System: Linux, Version: Ubuntu Linux (64-bit)
Number of virtual processors: 1
Memory Size: 2048 MB
Number of NICs: 1
NIC 1: VM Network
Adapter: E1000, Connect at Power On: Checked
SCSI controller: LSI Logic Parallel
Select a Disk: Create a new virtual disk
Create a Disk: 63 GB, No thin provisioning, No cluster features, Store with the
virtual machine
Advanced Options: Virtual Device Node = SCSI (0:0)
Remove Floppy Drive
Mount CD/DVD Drive to Ubuntu ISO (ubuntu-10.04.4-server-amd64.iso). Make
sure CD/DVD is set to Connect at power on
Set boot options to Force BIOS Setup so you can set CDROM to boot before the
Hard Disk

Install PuTTY
The 1st time I installed Ubuntu and Zimbra, I used the console for everything but it was
painfully slow to view man (manual) pages and navigating in VI (text editor). However, I
found out that PuTTY is a far better solution for your Ubuntu console because it handles
the screen draws much faster and allows for scrolling and copying text.
Download the portable edition and run the install...except it doesn't really "install" like a
normal program, it simply extracts to a specified folder and will run from that folder even if
you put it on a USB stick and carry over to a new computer (requires no install to run and
thus leaves a very small footprint on your system)
1. Start PuTTY
2. Type the following and click the Save button:
Host Name: mail (or the IP such as 192.168.107.25)
Port: 22
Connection type: SSH
Saved Sessions: zimbra
3. Now all you have to do is double-click on the zimbra session and it will connect to
your server (when online).
__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
#3 (permalink)
04-26-2012, 07:14 PM
LHammonds
Special Member

Posts: 138

Install Ubuntu Server

Install Ubuntu Server
NOTE: During the setup process, we are going to use the root account to make things easier.
Later on, it will be best to use the "sudo" command to only temporarily grant root access
rather than logging in with root access.
1. Power on the Virtual Machine (VM)
2. Press {ENTER} to accept English
3. Select Install Ubuntu Server {ENTER}
4. Press {ENTER} to accept English
5. Press {ENTER} to accept United States
6. Select No to not detect keyboard layout
7. Press {ENTER} to accept USA
8. Press {ENTER} to accept USA
9. Type mail {ENTER} (this is your hostname)
10. Press {ENTER} to accept detected time zone (America/Chicago)
11. Select Manual {ENTER}
12. Select SCSI3 (0,0,0) (sda) - 67.6 GB VMware Virtual disk {ENTER}
13. Select Yes to create new empty partition table, {ENTER}
14. Select pri/log 67.6 GB FREE SPACE {ENTER}
15. Select Create a new partition {ENTER}
16. Type 200 MB, {ENTER} (NOTE: This will be the /boot partition)
17. Select Primary {ENTER}
18. Select Beginning {ENTER}
19. Select Use as: Ext4 journaling file system {ENTER}
20. Select Ext2 file system {ENTER}
21. Select Mount point: / {ENTER}
22. Select /boot - static files of the boot loader {ENTER}
23. Select Bootable flag: off {ENTER} (NOTE: This toggles it on)
24. Select Done setting up the partition {ENTER}
25. Select Configure the Logical Volume Manager {ENTER}
26. Select Yes to write change to disks and configure LVM, {ENTER}
27. Select Create volume group {ENTER}
28. Type LVG {ENTER}
29. Select /dev/sda free #1 (67445; FREE SPACE), {SPACEBAR}, {ENTER}
30. Select Yes to write change to disks and configure LVM, {ENTER}
31. Select Create logical volume {ENTER}
32. Select LVG (67440MB) {ENTER}
33. Type swap {ENTER}
34. Type 8G {ENTER} (NOTE: This is double the amount of RAM)
35. Select Create logical volume {ENTER}
36. Select LVG (59441MB) {ENTER}
37. Type bak {ENTER}
38. Type 20G {ENTER}
39. Select Create logical volume {ENTER}
40. Select LVG (39443MB) {ENTER}
41. Type opt {ENTER}
42. Type 10G {ENTER}
43. Select Create logical volume {ENTER}
44. Select LVG (29444MB) {ENTER}
45. Type temp {ENTER}
46. Type 20G {ENTER}
47. Select Create logical volume {ENTER}
48. Select LVG (9445MB) {ENTER}
49. Type root {ENTER}
50. Type 9445MB {ENTER} (we are letting it take what is left over)
51. Select Finish {ENTER}
52. Select #1 8.0 GB directly under LVM VG LVG, LV swap, {ENTER}
53. Select Use as: do not use {ENTER}
54. Select swap area {ENTER}
55. Select Done setting up the partition {ENTER}
56. Select #1 9.4 GB directly under LVM VG LVG, LV root, {ENTER}
57. Select Use as: do not use {ENTER}
58. Select Ext4 journaling file system {ENTER}
59. Select Mount point: none {ENTER}
60. Select / - the root file system {ENTER}
61. Select Done setting up the partition {ENTER}
62. Select #1 20.0 GB directly under LVM VG LVG, LV bak, {ENTER}
63. Select Use as: do not use {ENTER}
64. Select Ext4 journaling file system {ENTER}
65. Select Mount point: none {ENTER}
66. Select Enter manually {ENTER}
67. Type /var/backup {ENTER}
68. Select Label: none {ENTER}
69. Type backup {ENTER}
70. Select Done setting up the partition {ENTER}
71. Select #1 10.0 GB directly under LVM VG LVG, LV opt, {ENTER}
72. Select Use as: do not use {ENTER}
73. Select Ext4 journaling file system {ENTER}
74. Select Mount point: none {ENTER}
75. Select /opt - add-on application software packages {ENTER}
76. Select Label: none {ENTER}
77. Type zimbra {ENTER}
78. Select Done setting up the partition {ENTER}
79. Select #1 20.0 GB directly under LVM VG LVG, LV temp, {ENTER}
80. Select Use as: do not use {ENTER}
81. Select Ext4 journaling file system {ENTER}
82. Select Mount point: none {ENTER}
83. Select Enter manually {ENTER}
84. Type /var/temp {ENTER}
85. Select Label: temp {ENTER}
86. Select Done setting up the partition {ENTER}
87. Here is what the screen looks like at this point: Partitions
88. Select Finish partitioning and write changes to disk {ENTER}
89. Select Yes to write changes to disk, {ENTER}
90. Type Administrator, {ENTER} for the full name (NOTE: Do not use "zimbra" as a
choice here)
91. Press {ENTER} to accept the default of the lowercase name of administrator
92. Type myadminpass, {ENTER}, myadminpass, {ENTER}
93. Select No, {ENTER} to not encrypt your home directory
94. Press {ENTER} to accept a blank line for the HTTP proxy
95. Select Install security updates automatically, {ENTER}
96. Highlight only OpenSSH server and press {SPACEBAR} to enable, {ENTER} to
continue. NOTE: This allows us to use PuTTY after installation to connect to the
server.
97. Select Yes, {ENTER} to install GRUB boot loader to the master boot record
98. Installation Complete - from the VM menu, select VM --> Edit Settings and select
CD/DVD Drive 1 and change to "Client Device" which will effectively remove the
ISO. Now press {ENTER} to reboot.

Initial Configurations
1. At the console login prompt, login with your administrator account (administrator /
myadminpass)
2. At the $ prompt, type sudo passwd root {ENTER}, type your administrator password
(myadminpass), it will ask for a new password, type myrootpass and verify. NOTE:
This enables the root account.
3. At the $ prompt, change to the super user root account by typing su {ENTER} and
then provide the new root password you just configured.
4. Type vi /etc/network/interfaces {ENTER} and change the following: (We need to
change the network interface card (NIC) from using DHCP to a static IP)
From:
Code:
iface eth0 inet dhcp

To:
Code:
iface eth0 inet static
address 192.168.107.25
netmask 255.255.255.0
gateway 192.168.107.1
network 192.168.107.0
broadcast 192.168.107.255

NOTE #1: You may need to manually remove the DHCP record (lease) associated to
this Ubuntu server from your DHCP server so the correct IP can be found by other
machines on the network. This can be avoided by temporarily configuring the VM
Network Adapter connection to be "Host Only Network" instead of "VM Network" so
the server is isolated during setup...at least until you reach the testing of the static IP
below.
NOTE #2: You might also need to manually add a HOST(A) record to your Windows
DNS server (for mail.mydomain.com and mail.work.mydomain.com)
5. Restart the network by typing /etc/init.d/networking restart
6. Sanity check! Type ifconfig and make sure the settings are correct. Then type ping
Google or similar and see if ping works.
7. Shutdown and power off the server by typing shutdown -P now {ENTER}
8. At this point forward, you can use PuTTY to access the console rather than the
console itself for better performance, ability to scroll, etc.
9. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 1
and description of Ubuntu Server 10.04.4 LTS, clean install, Static IP:
192.168.107.25 and click OK
__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
#4 (permalink)
04-26-2012, 07:22 PM
LHammonds
Special Member

Posts: 138

Volume / Disk Management

Volume / Disk Management
At this point, let's assume something has changed and we need additional storage (e.g.
acquired new company, added more people, etc.)
For this scenario, we are expecting storage space to require 25 GB for all user mailboxes. If
they need 25 GB for storage, let's double that amount for the actual size. Here is the planned
adjustments for each file system:
opt = 50 GB (double the expected/actual mailbox storage)
temp = 100 GB (double the opt size)
backup = 100 GB (double the opt size)
In the analysis and design section, we wanted to have some file systems smaller than the
logical volume on which they sit. This will allow us to allocate additional space when
needed. However, when we created the volumes, Ubuntu automatically expanded the file
systems to the maximum size of the volume. Normally, this is OK...but we want a system that
will allow growth when needed and ensure that we will have time to add additional hard
drives BEFORE they are needed which will keep us from being stuck between a rock and a
hard place!
The design calls for the backup, opt and temp file systems to be slightly smaller than the
maximum space available for the logical volume.
So, let's make the logical volumes an extra 25 GB larger. This means that we will need an
additional 275 GB of storage {(75 + 125 + 125 ) - 50}. If we add two drives that are 140 GB
each, that will be just enough to cover our needs. (NOTE: This was an arbitrary number
because I wanted to show you how to add 2 drives to the system)
If we were to type df -h right now, we should see something like this:
Code:
Filesystem
/dev/mapper/LVG-root
none
none
none
none
none
/dev/mapper/LVG-bak
/dev/mapper/LVG-opt
/dev/mapper/LVG-temp
/dev/sda1

Size
8.7G
1000M
1005M
1005M
1005M
1005M
19G
9.2G
19G
179M

Used
824M
184K
0
32K
0
0
172M
149M
172M
17M

Avail Use% Mounted on
7.5G 10% /
1000M
1% /dev
1005M
0% /dev/shm
1005M
1% /var/run
1005M
0% /var/lock
1005M
0% /lib/init/rw
18G
1% /var/backup
8.6G
2% /opt
18G
1% /var/temp
152M 10% /boot

Since I am running VMware, adding additional space is a snap. However, I will add it in such
a way that Ubuntu will see 2 drives added to the system just as if we were to add 2 physical
drives to the server.
1. Shutdown and power off the server by typing shutdown -P now {ENTER}
2. In the vSphere client, right-click the Virtual Machine and choose Edit Settings.
3. On the hardware tab, click the Add button and select Hard Disk. Click Next, choose
"Create a new virtual disk", click Next, set the size to 140 GB, click Next, Next,
Finish.
4. Add another 140 GB disk using the same steps above and click OK to close the
settings and allow VMware to process the changes.

Collect information about the newly added drives.
1. Start the Ubuntu server and connect using PuTTY.
2. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
3. Type pvdisplay which should show something similar to this:
Code:
PV Name
VG Name
PV Size
Allocatable
PE Size
Total PE
Free PE
Allocated PE
PV UUID

/dev/sda5
LVG
62.81 GiB / not usable 3.00 MiB
yes (but full)
4.00 MiB
16079
0
16079
XjUHyI-kloS-kicz-jLdd-E01t-7RYP-K3YqvM

The important bits of info here are the PV Name and VG Name for our existing
configuration.
4. Type fdisk -l which should show something similar to this (however I abbreviated it
to show just the important parts):
Code:
Disk /dev/sda: 67.6 GB, 67645734912 bytes
Device Boot
Start
End
Blocks
Id
/dev/sda1
*
1
25
194560
83
Partition 1 does not end on cylinder boundary.
/dev/sda2
25
8224
65862657
5
/dev/sda5
25
8224
65862656
8e
Disk /dev/sdb: 150.3 GB, 150323855360 bytes
Disk /dev/sdb doesn't contain a valid partition table
Disk /dev/sdc: 150.3 GB, 150323855360 bytes
Disk /dev/sdc doesn't contain a valid partition table

System
Linux
Extended
Linux LVM

The important bits of info here are the device paths for the new drives which are
highlighted in red.

Prepare the first drive (/dev/sdb) to be used by the LVM
Type the following:
Code:
fdisk /dev/sdb
n (Create New Partition)
p (Primary Partition)
1 (Partition Number)
{ENTER} (use default for first cylinder)
{ENTER} (use default for last cylinder)
t (Change partition type)
8e (Set to Linux LVM)
p (Preview how the drive will look)
w (Write changes)

Prepare the second drive (/dev/sdc) to be used by the LVM
Do the exact same steps as above but start with fdisk /dev/sdc
Create physical volumes using the new drives
If we type fdisk -l, we now see /dev/sdb1 and /dev/sdc1 which are Linux LVM partitions.
Type the following to create physical volumes:
Code:
pvcreate /dev/sdb1
pvcreate /dev/sdc1

Now add the physical volumes to the volume group (LVG) by typing the following:
Code:
vgextend LVG /dev/sdb1
vgextend LVG /dev/sdc1

Now that the space of both drives have been added to the logical volume group called LVG,
we can now allocate that space to grow the logical volume.
To get a list of volume paths to use in the next commands, type lvscan to show your current
volumes and their sizes.
Type the following to grow each volume by a specified amount (the number after the plus
sign):
Code:
lvextend -L+65G /dev/LVG/opt
lvextend -L+105G /dev/LVG/bak
lvextend -L+105G /dev/LVG/temp

or you can specify the exact size by excluding the plus sign and specifying the end-result size
you want:
Code:
lvextend -L75G /dev/LVG/opt
lvextend -L125G /dev/LVG/bak
lvextend -L125G /dev/LVG/temp

To see the new sizes, type lvscan
The last thing to do now is the actual growth of the file systems. We want to grow the
existing file systems but only to a certain amount so we do not take up all the space in the
volume...we want room to grow in the future so we have time to order and install new drives
when needed.
Code:
resize2fs /dev/LVG/opt 50G
resize2fs /dev/LVG/bak 100G
resize2fs /dev/LVG/temp 100G

If we need to increase space in /opt at a later point, we can issue the following command
(without any downtime):
Code:
resize2fs /dev/LVG/opt 51G

We could continue to increase this particular file system all the way until we reach the limit
of the volume which is 75 GB at the moment.
Remember, df -h will tell you the size of the file system and lvscan will tell you the size of
the volumes where the file systems live in.
If we were to type df -h right now, we should see something like this:
Code:
Filesystem
/dev/mapper/LVG-root
none
none
none
none

Size
8.7G
1000M
1005M
1005M
1005M

Used
824M
200K
0
32K
0

Avail Use% Mounted on
7.5G 10% /
1000M
1% /dev
1005M
0% /dev/shm
1005M
1% /var/run
1005M
0% /var/lock
none
1005M
/dev/mapper/LVG-bak
99G
/dev/mapper/LVG-opt
50G
/dev/mapper/LVG-temp
99G
/dev/sda1
179M

0 1005M
188M
94G
159M
47G
188M
94G
17M 152M

0%
1%
1%
1%
10%

/lib/init/rw
/var/backup
/opt
/var/temp
/boot

EDIT (2012-05-03): In favor of manage by exception, I wrote a script that can be scheduled
to run daily to check the file systems to see if they are getting close to filling up and will
automatically expand them a little bit and give you an email notice. Everything is done on the
gigabyte level. If you do not want the script to perform the increase, simply add a pound sign
in front of the resize2fs command on line 64 to comment it out. Might also want to modify
the log and email messages so it does not look like it actually "performed" the resize but
instead is telling YOU how to perform the resize.
Here are the lines I added to my crontab schedule which will check each file system I expect
will grow on a daily basis @ 1am, 2am and 3am. I have them checking to see if we have less
than 5GB available and if so, it will try to increase by 1GB:
Code:
0 1 * * * /var/scripts/prod/check-storage.sh opt 5 1 > /dev/null 2>&1
0 2 * * * /var/scripts/prod/check-storage.sh bak 5 1 > /dev/null 2>&1
0 3 * * * /var/scripts/prod/check-storage.sh temp 5 1 > /dev/null 2>&1

/var/scripts/prod/check-storage.sh
Code:
#!/bin/bash
#############################################
## Name
: check-storage.sh
## Version
: 1.2
## Date
: 2012-05-01
## Author
: LHammonds
## Purpose
: Check available space for a file system and expand if
necessary.
## Compatibility : Verified on Ubuntu Server 10.04.4 LTS
## Requirements : None
## Run Frequency : Recommend once per day for each FS to monitor.
## Parameters
:
##
1 = (Required) File System name (e.g. opt)
##
2 = (Required) File System Threshold (e.g. 2G)
##
3 = (Required) Amount to increase File System (e.g. 1G)
## Exit Codes
:
##
0 = Success (either nothing was done or FS expanded without error)
##
1 = ERROR: Missing or incorrect parameter(s)
##
2 = ERROR: Invalid parameter value(s)
##
4 = ERROR: Lock file detected
##
8 = ERROR: Resize2fs error
##
16 = SEVERE: No room to expand
##
32 = ERROR: Script not run by root user
################ CHANGE LOG #################
## DATE
WHO WHAT WAS CHANGED
## ---------- --- ---------------------------## 2012-05-01 LTH Created script.
## 2012-05-02 LTH Improved log messages.
## 2012-05-02 LTH Improved email messages.
#############################################
## Import standard variables and functions. ##
source /var/scripts/common/standard.conf
## Define local variables.
LOGFILE="${TEMPDIR}/check-storage.log"
LOCKFILE="${TEMPDIR}/check-storage.lock"
ErrorFlag=0
ReturnCode=0
#######################################
##
FUNCTIONS
##
#######################################
function f_cleanup()
{
if [ -f ${LOCKFILE} ];then
## Remove lock file so other check space jobs can run.
rm ${LOCKFILE} 1>/dev/null 2>&1
fi
exit ${ErrorFlag}
}
function f_showhelp()
{
echo -e "nUsage : ${SCRIPTNAME} FileSystemName ThresholdSizeInGB
AmountToIncreaseByInGBn"
echo -e "nExample: ${SCRIPTNAME} opt 2 1n"
}
function f_auto-increment()
{
let RoomInLV=${LVSize}-${FSSize}
if [[ ${RoomInLV} -gt ${FSIncreaseBy} ]]; then
## There is room in the LV to increase space to the FS.
resize2fs ${FSVol} ${NewFSSize}G
ReturnCode=$?
echo "`date +%Y-%m-%d_%H:%M:%S` --- resize2fs ${FSVol} ${NewFSSize}G,
ReturnCode=${ReturnCode}" | tee -a ${LOGFILE}
if [[ ${ReturnCode} -ne 0 ]]; then
## There was an error in resize2fs.
return ${ReturnCode}
fi
else
## There is not enough room in the LV to increase space in the FS.
return 50
fi
return 0
}
#######################################
##
MAIN PROGRAM
##
#######################################
if [ -f ${LOCKFILE} ]; then
# Lock file detected. Abort script.
echo "Check space script aborted"
echo "This script tried to run but detected the lock file: ${LOCKFILE}"
echo "Please check to make sure the file does not remain when check space
is not actually running."
f_sendmail "ERROR: check storage script aborted" "This script tried to
run but detected the lock file: ${LOCKFILE}nnPlease check to make sure
the file does not remain when check space is not actually running.nnIf
you find that the script is not running/hung, you can remove it by typing
'rm ${LOCKFILE}'"
ErrorFlag=4
f_cleanup
else
echo "`date +%Y-%m-%d_%H:%M:%S` ${SCRIPTNAME}" > ${LOCKFILE}
fi
## Requirement Check: Script must run as root user.
if [ "$(id -u)" != "0" ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo "ERROR: Root user required to run this script."
echo ""
ErrorFlag=32
f_cleanup
fi
## Check existance of required command-line parameters.
case "$1" in
"")
f_showhelp
ErrorFlag=1
f_cleanup
;;
--help|-h|-?)
f_showhelp
ErrorFlag=1
f_cleanup
;;
*)
FSName=$1
;;
esac
case "$2" in
"")
f_showhelp
ErrorFlag=1
f_cleanup
;;
--help|-h|-?)
f_showhelp
ErrorFlag=1
f_cleanup
;;
*)
FSThreshold=$2
;;
esac
case "$3" in
"")
f_showhelp
ErrorFlag=1
f_cleanup
;;
--help|-h|-?)
f_showhelp
ErrorFlag=1
f_cleanup
;;
*)
FSIncreaseBy=$3
;;
esac
## Check validity of File System name.
case "${FSName}" in
"opt")
FSVol="/dev/LVG/opt"
FSMap="/dev/mapper/LVG-opt"
;;
"bak")
FSVol="/dev/LVG/bak"
FSMap="/dev/mapper/LVG-bak"
;;
"temp")
FSVol="/dev/LVG/temp"
FSMap="/dev/mapper/LVG-temp"
;;
*)
echo "ERROR: ${FSName} does not match a known file system defined in
this script."
f_showhelp
ErrorFlag=2
f_cleanup
;;
esac
## Check validity of threshold value.
test ${FSThreshold} -eq 0 1>/dev/null 2>&1
if [[ $? -eq 2 ]]; then
## Threshold parameter is not an integer.
echo "ERROR: ${FSThreshold} is not an integer."
f_showhelp
ErrorFlag=2
f_cleanup
fi
## Check validity of increment value.
test ${FSIncreaseBy} -eq 0 1>/dev/null 2>&1
if [[ $? -eq 2 ]]; then
## FSIncreaseBy parameter is not an integer.
echo "ERROR: ${FSIncreaseBy} is not an integer."
f_showhelp
ErrorFlag=2
f_cleanup
fi
## Get available space for the file system.
FSAvailable="`df --block-size=g ${FSMap} | awk '{ print $4 }' | tail -n 1 |
sed 's/G//'`"
## Get the current size of the File System.
FSSize="`df --block-size=g ${FSMap} | awk '{ print $2 }' | tail -n 1 | sed
's/G//'`"
## Get the current size of the Logical Volume for the File System
LVSize="`lvs --noheadings --nosuffix --units=g ${FSMap} | awk '{ print $4}'
| sed 's/[.].*//'`"
## Calculate the new size of the FS in case we need it.
let NewFSSize=${FSSize}+${FSIncreaseBy}
if [[ ${FSAvailable} -lt ${FSThreshold} ]]; then
echo "`date +%Y-%m-%d_%H:%M:%S` - Starting expansion of ${FSVol}" | tee a ${LOGFILE}
echo "`date +%Y-%m-%d_%H:%M:%S` --- LVSize=${LVSize}GB,
FSSize=${FSSize}GB, FSAvail=${FSAvailable}GB, FSThreshold=${FSThreshold}GB,
FSIncreaseBy=${FSIncreaseBy}GB" | tee -a ${LOGFILE}
## Run the auto-expansion function.
f_auto-increment
ReturnCode=$?
case ${ReturnCode} in
0)
f_sendmail "NOTICE: File System Expanded" "${FSVol} was expanded
because it was nearing max capacity. Please review disk space usage and
plan appropriately. LVSize=${LVSize}GB, FSSize=${FSSize}GB,
FSAvailable=${FSAvailable}GB, FSThreshold=${FSThreshold}GB,
FSIncreaseBy=${FSIncreaseBy}GB"
;;
50)
echo "`date +%Y-%m-%d_%H:%M:%S` - SEVERE: No room to expand ${FSVol}" |
tee -a ${LOGFILE}
ErrorFlag=16
f_sendmail "SEVERE: No room to expand ${FSVol}" "There is not enough
room in the Logical Volume to expand the ${FSVol} File System. Immediate
action is required. Make sure there is free space in the Volume Group
'LVG' and then expand the Logical Volume...then expand the File
System.nnLVSize=${LVSize}GB, FSSize=${FSSize}GB,
FSAvailable=${FSAvailable}GB, FSThreshold=${FSThreshold}GB,
FSIncreaseBy=${FSIncreaseBy}GB.nnType 'vgs' to see if there is any free
space in the Volume Group which can be given to the Logical Volume.nnType
'lvs' to see the current sizes of the LVs.nnType 'lvdisplay' to see a
list of Logical Volumes so you can get the LV Name which is used in the
lvextend and resize2fs commands.nnType 'lvextend -L+1G /dev/LVG/opt' if
you want to extend the opt Logical Volume by 1 gigabyte (assuming there is
1GB available in the Volume Group).nnType 'df --block-size=g' to see a
list of file systems and their associated size and available space.nnType
'resize2fs /dev/LVG/opt ${NewFSSize}G' to set the size of opt to
${NewFSSize} gigabytes. Make sure you set the size to the desired endresult which should be LARGER than the current FS size so you do not lose
data."
;;
*)
echo "`date +%Y-%m-%d_%H:%M:%S` - ERROR: Expansion failure for
${FSVol}" | tee -a ${LOGFILE}
ErrorFlag=8
f_sendmail "ERROR: File System Expansion Failed" "${FSVol} Expansion
failed with return code of ${ReturnCode}. LVSize=${LVSize}GB,
FSSize=${FSSize}GB, FSAvailable=${FSAvailable}GB,
FSThreshold=${FSThreshold}GB, FSIncreaseBy=${FSIncreaseBy}GB"
;;
esac
echo "`date +%Y-%m-%d_%H:%M:%S` - Finished expansion of ${FSVol}" | tee a ${LOGFILE}
else
echo "`date +%Y-%m-%d_%H:%M:%S` - ${FSVol}
${FSAvailable}G>${FSThreshold}G No action required." | tee -a ${LOGFILE}
fi
## Perform cleanup routine.
f_cleanup

Here is the typical output when it does not have to increase the FS:
/var/temp/check-storage.log
Code:
2012-05-01_01:00:00
2012-05-01_02:00:00
2012-05-01_03:00:00
2012-05-02_01:00:00

-

/dev/LVG/opt 44G>5G No action required.
/dev/LVG/bak 91G>5G No action required.
/dev/LVG/temp 93G>5G No action required.
/dev/LVG/opt 44G>5G No action required.
2012-05-02_02:00:00
2012-05-02_03:00:00
2012-05-03_01:00:00
2012-05-03_02:00:00
2012-05-03_03:00:00

-

/dev/LVG/bak 91G>5G No action required.
/dev/LVG/temp 93G>5G No action required.
/dev/LVG/opt 44G>5G No action required.
/dev/LVG/bak 91G>5G No action required.
/dev/LVG/temp 93G>5G No action required.

Here is a sample of what the log will look like when it perform increases...notice how I had to
increase the threshold in order for it to fire off the increase (but it still just issued a single
gigabyte increase):
/var/temp/check-storage.log
Code:
2012-05-02_01:00:00 - Starting expansion of /dev/LVG/opt
2012-05-02_01:00:00 --- LVSize=75GB, FSSize=50GB, FSAvail=44GB,
FSThreshold=55GB, IncreaseBy=1GB
2012-05-02_01:00:00 --- resize2fs /dev/LVG/opt 51, ReturnCode=0
2012-05-02_01:00:00 - Finished expansion of /dev/LVG/opt
2012-05-02_02:00:00 - Starting expansion of /dev/LVG/bak
2012-05-02_02:00:00 --- LVSize=125GB, FSSize=99GB, FSAvail=91GB,
FSThreshold=100GB, IncreaseBy=1GB
2012-05-02_02:00:00 --- resize2fs /dev/LVG/bak 100, ReturnCode=0
2012-05-02_02:00:00 - Finished expansion of /dev/LVG/bak
2012-05-02_03:00:00 - Starting expansion of /dev/LVG/temp
2012-05-02_03:00:00 --- LVSize=125GB, FSSize=99GB, FSAvail=93GB,
FSThreshold=100GB, IncreaseBy=1GB
2012-05-02_03:00:00 --- resize2fs /dev/LVG/temp 100, ReturnCode=0
2012-05-02_03:00:00 - Finished expansion of /dev/LVG/temp

__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
Last edited by LHammonds; 05-03-2012 at 06:58 AM..

#5 (permalink)
04-26-2012, 07:26 PM
LHammonds
Special Member
Software Configurations

Software Configurations
1. Start the Ubuntu server and connect using PuTTY.
2. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)

Posts: 138
3. At the $ prompt, type aptitude -y install vim-nox for use instead of the built-in VI
editor. more info
4. At the $ prompt, type aptitude -y install bind9 to install a local DNS server.
5. At the $ prompt, type aptitude -y install p7zip-full to install 7-zip archive utility.
6. Type dpkg-reconfigure dash and answer No
7. Remove AppArmor to avoid problems by typing the following:
Code:
/etc/init.d/apparmor stop
update-rc.d -f apparmor remove
aptitude remove apparmor apparmor-utils

8. Reboot the server by typing reboot

VMware Tools
If you are installing under VMware like me, be sure to install the tools to insure maximum
performance in a virtual environment.
1. In the VM toolbar for the VM, click Guest, Install VMware Tools
2. At the Ubuntu prompt, type the following:
Code:

mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
ls /mnt/cdrom
tar zxvf /mnt/cdrom/VMwareTools-x.x.x-xxxx.tar.gz -C /tmp/
(use
the correct numbers version discovered from the list command in
the prior step)
cd /tmp/vmware-tools-distrib/
./vmware-install.pl -d
reboot

Configure Ubuntu for File Sharing
This file sharing section is optional but can be handy if you need to swap files between the
Linux server and a Windows machine.
This documentation will utilize this share for passing pre-configured files (configs, scripts,
etc.) to make it faster/easier during installation.
1. Start the Ubuntu server and connect using PuTTY.
2. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
3. Install Samba by typing aptitude -y install samba smbfs (NOTE: To share a folder
with Windows, you just need the samba package, to connect to a Windows share, you
need both samba and smbfs)
4. Type the following commands:
Code:

cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
mkdir -p /srv/samba/share
chown nobody:nogroup /srv/samba/share/
chmod 0777 /srv/samba/share

5. Edit the configuration file by typing vi /etc/samba/smb.conf
6. Change workgroup = WORKGROUP to workgroup = work (you are using the
domain alias)
7. Change:
Code:
#

security = user

to:
Code:
security = user

8. Add the following section to the end of the file:
Code:
[share]
comment = Ubuntu File Server Share
path = /srv/samba/share
browsable = yes
guest ok = yes
read only = no
create mask = 0755

9. Save and exit the file.
10. Restart the samba services to utilize the new configuration by typing:
Code:
restart smbd
restart nmbd
11. You should now be able to click Start --> Run and type mail or 192.168.107.25
{ENTER} and see an explorer window with a Share folder. Drag-n-drop a file into
the Share folder. If it worked, it will not display an error message and you should be
able to view it from the server by typing ls -l /srv/samba/share/
12. Shutdown and power off the server by typing shutdown -P now {ENTER}
13. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 2
and description of Ubuntu Server 10.04.4 LTS, File share configured, Static IP:
192.168.107.25. The Snapshot Manager should now have a nice hierarchy of
snapshots (STEP 1 --> STEP 2 --> You are here)

Configure Windows Remote Mount Point
The remote offsite location is a Windows 2008 server that has a vast amount of hard drive
space and currently backs up other servers.
Part of the backup process will be to write files to a mounted folder to a Windows share.
First, let's document the variables for this solution below and highlight them in red
throughout the document for easy identification.
The values below are merely samples which you need to change in order to match your
environment:
Windows AD Domain Name: work
Windows Server Name: SRV-Backup
Windows Server IP: 192.168.107.218
Windows Share Name: zimbra
Windows Physical Share Location: D:Zimbra
Windows Share ID: zimbrashare
Windows Share Password: zimbrapassword

Create a share on a Windows 2008 server
1. In Windows Explorer, right-click on the D:Zimbra folder and select Properties
2. Click the Sharing tab
3. Click the Advanced Sharing button
4. Place a checkmark beside Share this folder
5. Change the Share name to zimbra
6. Set the Comment to Zimbra Backup
7. Click the Permissions button
8. Select Everyone and click the Remove button
9. Click the Add button
10. Type in your zimbra share account: workzimbrashare and click the Check Names
button, click OK
11. Place a checkmark for Allow Full Control and click OK, click OK, click OK
12. Create a text file in the root of the shared folder called "online.txt" and you might
want to add some text inside saying to never delete this file because it is used (will be)
by a Zimbra backup script. Probably a good idea to make it read-only as well.
Example: [B]D:zimbraonline.txt[B]

Create an NFS mount to the Windows 2008 server
Connecting to a Windows share requires the samba and smbfs packages to be installed. If
you did not install them (from a prior section), type aptitude -y install samba smbfs
1. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
2. Type the following commands:
Code:

mkdir -p /mnt/backup
chown root:root /mnt/backup
chmod 0755 /mnt/backup
echo "This file is used to tell if the mount is active or not" >
/mnt/backup/offline.txt
chown root:root /mnt/backup/offline.txt
chmod 0444 /mnt/backup/offline.txt
touch /etc/cifspw
chmod 0600 /etc/cifspw

3. Type vi /etc/cifspw and add the following text, save and exit the file:
Code:

username=workzimbrashare
password=zimbrapassword

4. Type vi /etc/hosts and add the following line anywhere in the file:
Code:

192.168.107.218

srv-backup

5. At this point, you might want to type ping srv-backup to make sure you typed the
right IP address as well as seeing a good response.
6. To mount this system for backups, type the following command:
Code:

mount -t cifs //srv-backup/zimbra /mnt/backup --options
nouser,rw,nofail,noatime,noexec,credentials=/etc/cifspw

7. To test it, type cp /etc/hosts /mnt/backup/hosts.txt and look on the Windows server
and see if the file shows up. Then type rm /mnt/backup/hosts.txt and verify that the
file was deleted on the windows server.
8. This would also be a good time to verify that you can see the "online.txt" file that will
be used by the backup script. Type ls -l /mnt/backup/*.txt
9. To dismount the windows share, type the following command:
Code:

umount /mnt/backup

The scripts will call a common mount and unmount function to connect to this share only
when needed.
However, if you would rather have it mounted all the time (even after a reboot), do the
following (but remember to not use the mount/umount functions in the scripts later):
1. Type vi /etc/fstab and add the following line at the bottom of the file:
Code:
//srv-backup/zimbra
/mnt/backup
cifs
nouser,rw,nofail,noatime,noexec,credentials=/etc/cifspw

0

2. Type mount -a and if it does not spew out any error messages, it will quietly mount
the share.
3. To test it, type cp /etc/hosts /mnt/backup/hosts.txt and look on the Windows server
and see if the file shows up. Then type rm /mnt/backup/hosts.txt and verify that the
file was deleted on the windows server.
4. If you need to unmount it, simply type umount /mnt/backup and it will remain
unmounted until you reboot. To make it permanent, you need to remove the line you
added in the /etc/fstab file.

Sometimes it is helpful during tests to toggle the mount on or off so here is a script you might
find helpful. You can find the contents of "standard.conf" file further down the thread.
togglemount.sh
Code:
#!/bin/bash
#############################################
## Name
: togglemount.sh
## Version
: 1.0
## Date
: 2011-11-05
## Author
: LHammonds

0
## Compatibility : Ubuntu Server 10.04.4 LTS
## Purpose
: Toggle the mount status of a pre-configured backup
mount.
## Run Frequency : Manual as needed.
## Exit Codes
:
##
0 = success
##
1 = failure
################ CHANGE LOG #################
## DATE
WHO WHAT WAS CHANGED
## ---------- --- ---------------------------## 2011-11-05 LTH Created script.
#############################################
## Import common variables and functions. ##
source /var/scripts/common/standard.conf
ERRORFLAG=0
if [ -f ${OFFSITEDIR}/offline.txt ]; then
echo "Windows share is not mounted. Mounting share now..."
f_mount
sleep 2
if [ -f ${OFFSITEDIR}/online.txt ]; then
echo "Mount successful. Listing contents:"
else
echo "Mount failed. Listing contents:"
ERRORFLAG=1
fi
else
echo "Windows share is mounted. Dismounting share now..."
f_umount
sleep 2
if [ -f ${OFFSITEDIR}/offline.txt ]; then
echo "Dismount successful. Listing contents:"
else
echo "Dismount failed. Listing contents:"
ERRORFLAG=1
fi
fi
ls -l ${OFFSITEDIR}
exit ${ERRORFLAG}

__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
#6 (permalink)
04-26-2012, 07:27 PM
LHammonds
Special Member
Configure DNS

Configure Domain Resolution (DNS)

Posts: 138
1. Connect to the server using PuTTY
2. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
3. Sanity check! Make sure BIND is running. Type /etc/init.d/bind9 status
4. At this point, you can save yourself a lot of typing if you have a copy of the
configuration files on your PC and simply copy them to the share. Then you can set
the appropriate file permissions and copy them where they need to go. But if not and
this is your 1st time installing the server, here are the details for configuring by hand.
5. Edit the hosts by typing vi /etc/hosts and change the following:
From:
Code:
127.0.0.1
127.0.1.1

localhost
mail.mydomain.com mail

To:
Code:
127.0.0.1
localhost.localdomain localhost
192.168.107.25 mail.mydomain.com mail

6. Edit the DNS servers by typing vi /etc/resolv.conf and set it to the following:
Code:
nameserver 127.0.0.1
nameserver 192.168.107.23
nameserver 192.168.107.212
nameserver 200.100.10.1
nameserver 200.100.10.2
domain mydomain.com
search mydomain.com

7. Type the following commands:
Code:
mkdir /var/cache/bind/internal
mkdir /var/cache/bind/external
touch /var/cache/bind/internal/db.mydomain.com
touch /var/cache/bind/internal/db.107.168.192.in-addr.arpa
touch /var/cache/bind/external/db.mydomain.com
cp /etc/bind/named.conf.options /etc/bind/named.conf.options.bak
cp /etc/bind/named.conf.local /etc/bind/named.conf.local.bak
cp /etc/bind/named.conf.default-zones
/etc/bind/named.conf.default-zones.bak
8. Stop the DNS server by typing /etc/init.d/bind9 stop
9. Edit the DNS options by typing vi /etc/bind/named.conf.options and set the
following:
Code:
options {
directory "/var/cache/bind";
query-source address * port 53;
forwarders {
200.100.10.1; 200.100.10.2;
};
auth-nxdomain no;
# conform to RFC1035
listen-on-v6 { any; };
};

NOTE: The IP addresses are public IP addresses of the DNS servers you use in the
outside world. The query-source address line is to allow your machine to hit the DNS
if oddball DNS ports are blocked. You can leave it commented if you do not need it.
10. Restart the network by typing /etc/init.d/networking restart
11. Type the following vi /etc/hostname and add the following text, save and exit:
Code:
mail.mydomain.com

12. To check results, type hostname and then hostname -f which should result with:
Code:
mail
mail.mydomain.com

13. Edit the local DNS file by typing vi /etc/bind/named.conf.local and set the
following:
Code:
acl internals {
127.0.0.0/8;
192.168.107.0/24;
};
view "internal" {
match-clients { internals; };
recursion yes;
zone "mydomain.com" {
type master;
file "/var/cache/bind/internal/db.mydomain.com";
};
zone "107.168.192.in-addr.arpa" {
type master;
file "/var/cache/bind/internal/db.107.168.192.inaddr.arpa";
};
};
view "external" {
match-clients { any; };
recursion no;
zone "mydomain.com" {
type master;
file "/var/cache/bind/external/db.mydomain.com";
};
};

14. Edit the internal reverse zone file by typing vi
/var/cache/bind/internal/db.107.168.192.in-addr.arpa and set the following:
Code:
$TTL 86400
@
IN

1

NS
PTR

SOA
mail.mydomain.com. root.mydomain.com. (
201109231448
; Serial (increment after edit)
604800
; Refresh
86400
; Retry
2419200
; Expire
86400)
; Negative Cache TTL
mail.mydomain.com.
mail.mydomain.com.

15. Edit the internal zone file by typing vi /var/cache/bind/internal/db.mydomain.com
and set the following:
Code:
; mydomain.com
$TTL
86400
@
IN
SOA
root.mydomain.com. (

mail.mydomain.com.
201109231335

; Serial

604800
86400
2419200
604800)

;
;
;
;

(increment after edit)
Refresh
Retry
Expire
Negative Cache

TTL
; Define the nameservers and the mail servers
@
IN
NS
192.168.107.25.
IN
MX
10
mail.mydomain.com.
IN
A
192.168.107.25
mail
IN
A
192.168.107.25

16. Edit the external zone file by typing vi /var/cache/bind/external/db.mydomain.com
and set the following:
Code:
; mydomain.com
$TTL
86400
@
IN
SOA
root.mydomain.com. (

mail.mydomain.com.
201109231335

; Serial

604800
86400
2419200
604800)

;
;
;
;

(increment after edit)
Refresh
Retry
Expire
Negative Cache

TTL
; Define the nameservers and the mail servers
@
IN
NS
198.100.100.100.
IN
MX
10
mail.mydomain.com.
IN
A
198.100.100.100
mail
IN
A
198.100.100.100

17. Since views were used, they also need to be used in the default zone. Type vi
/etc/bind/named.conf.default-zones and set the following:
Code:
// prime the server with knowledge of the root servers
acl internals-default {
127.0.0.0/8;
192.168.107.0/24;
192.168.106.0/24;
here.
};

// Keep adding all your internal subnets

view "internal-default" {
match-clients { internals-default; };
recursion yes;
zone "." {
type hint;
file "/etc/bind/db.root";
};
// be authoritative for the localhost forward and reverse zones,
and for
// broadcast zones as per RFC 1912
zone "localhost" {
type master;
file "/etc/bind/db.local";
};
zone "127.in-addr.arpa" {
type master;
file "/etc/bind/db.127";
};
zone "0.in-addr.arpa" {
type master;
file "/etc/bind/db.0";
};
zone "255.in-addr.arpa" {
type master;
file "/etc/bind/db.255";
};
};

18. Ensure the correct ownership and permissions of all config files:
Code:
chown
chown
chmod
chmod

root:bind /var/cache/bind/internal/*
root:bind /var/cache/bind/external/*
0644 /var/cache/bind/internal/*
0644 /var/cache/bind/external/*

19. Start the DNS server by typing /etc/init.d/bind9 start
20. That was a lot of typing and room for error so check the log for any errors: vi
/var/log/daemon.log
21. Sanity check! At this point, if you type nslookup mail.mydomain.com, you should
see that your internal DNS server (127.0.0.1) returned the result of your internal IP
address (192.168.107.25 for your FQDN of mail.mydomain.com)
22. Sanity check! Type dig mydomain.com mx and make sure you see a status of
NOERROR along with an MX record to your FQDN, NS record for your internal IP
and an A record your FQDN to your internal IP.
23. Shutdown and power off the server by typing shutdown -P now {ENTER}
24. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 3
and description of Ubuntu Server 10.04.4 LTS, Split-DNS configured, Static IP:
192.168.107.25. Click OK. The Snapshot Manager should now have a nice hierarchy
of snapshots (STEP 1 --> STEP 2 --> STEP 3 --> You are here)

Final Ubuntu Changes
1. Start the Ubuntu server and connect using PuTTY.
2. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
3. Update the package database by typing aptitude update
4. Install the latest updates by typing aptitude -y safe-upgrade
5. Shutdown and power off the server by typing shutdown -P now {ENTER}
6. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 4
and description of Ubuntu Server 10.04.4 LTS, all patches applied, Static IP:
192.168.107.25. The Snapshot Manager should now have a nice hierarchy of
snapshots (STEP 1 --> STEP 2 --> STEP 3 --> STEP 4 --> You are here)
7. NOTE: Over time, upgrades to the kernel can start taking up space in /etc/src. I found
this out because my root partition started to get full. When I typed this command: du sh /usr/src/* I found out there was over a gigabyte of old files. To cleanly clear out
old an unused headers, type the following commands:
Code:

apt-get -f install
apt-get autoremove

__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
#7 (permalink)
04-26-2012, 07:32 PM
LHammonds
Special Member

Posts: 138

Install Zimbra

Install Zimbra
NOTE: Install Zimbra by typing "./install.sh" and uninstall by typing "./install.sh -u"
Prerequisite packages:
NPTL
sudo-1.7.2p1-1ubuntu5.3
libidn11-1.15-2
libpcre3-7.8-3build1
libgmp3c2-2:4.3.2+dfsg-1ubuntu1
libexpat1-2.0.1-7ubuntu1
libstdc++6-4.4.3-4ubuntu5
libperl5.10-5.10.1-8ubuntu2.1

Suggested prerequisites:
perl-5.10.1
sysstat
sqlite3

Install Procedure:
1. Start the Ubuntu server and connect using PuTTY.
2. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
3. Download the Open Source Edition from Open Source Edition Downloads: Enterprise
Messaging and Collaboration Software by Zimbra
Method #1 - Download from your PC
A. Download the .tgz file and copy it to the Ubuntu share --> mailshare or
192.168.107.25share
B. Once copied to the server, access the console and type the following:
Code:
mv /srv/samba/share/zcs* /var/temp

Method #2 - Download directly from the server
A. Obtain the download URL from the Zimbra OSE page
B. Type the following commands on the server console (using the correct URL)
Code:
cd /var/temp
wget http://files.zimbra.com/downloads/7.2.0_GA/zcs7.2.0_GA_2669.UBUNTU10_64.20120410002303.tgz

4. Extract the archive by typing the following commands:
Code:
mkdir /var/temp/install
tar -C /var/temp/install --strip-components=1 -xzf /var/temp/zcs*

5. Start the installation program by typing the following:
Code:
cd /var/temp/install
./install.sh

6. Agree to license agreement? Press y {ENTER}
7. If you are missing any prerequisites, exit the installation and install them. You can
install all at one time by separating each name with a space after aptitude install such
as the following:
Code:
aptitude -y install sysstat sqlite3

8. Install zimbra-ldap? Press y {ENTER}
9. Install zimbra-logger? Press y {ENTER}
10. Install zimbra-mta? Press y {ENTER}
11. Install zimbra-snmp? Press y {ENTER}
12. Install zimbra-store? Press y {ENTER}
13. Install zimbra-apache? Press y {ENTER}
14. Install zimbra-spell? Press y {ENTER}
15. Install zimbra-memcached? Press n {ENTER} (if multi-server, press y instead)
16. Install zimbra-proxy? Press n {ENTER} (if multi-server, press y instead)
17. The system will be modified. Continue? Press y {ENTER}
18. DNS ERROR resolving MX for mail.mydomain.com. Change domain name? Press y
{ENTER}
19. Now we put the correct domain name in so type mydomain.com {ENTER}
20. You are presented a menu for resolving unconfigured options, press 3 {ENTER}
21. Select Admin password, press 4 {ENTER}. Then type your new password
(myzimbrapass) {ENTER}
22. Press r {ENTER} for previous menu
23. Press a {ENTER} to apply changes.
24. Press y {ENTER}, {ENTER} to save configuration (/opt/zimbra/config.9066)
25. The system will be modified - continue? Press y {ENTER}
26. Notify Zimbra of your installation? Press n {ENTER} (feel free to answer yes if this
is not a test system)
27. Press {ENTER} to exit setup. NOTE: Log files placed in /opt/zimbra/log
28. Shutdown and power off the server by typing the following:
Code:
/etc/init.d/zimbra stop
shutdown -P now

29. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 5
and description of Ubuntu Server 10.04.4 LTS, Zimbra 7.2.0 OSE installed, Static
IP: 192.168.107.25. The Snapshot Manager should now have a nice hierarchy of
snapshots (STEP 1 --> STEP 2 --> STEP 3 --> STEP 4 --> STEP 5 --> You are here)

Admin Console and Initial Test
1. Start the Ubuntu server.
2. Access the webmail control panel by opening a web browser and typing this in the
address bar: https://192.168.107.25:7071
3. If your browser barks about an untrusted connection, tell it to continue anyway and
add an exception for it so it will not have a problem with it next time.
4. Login as admin@mydomain.com / myrootpassword
5. Create a new user account.
6. When done creating a new user, open a new browser tab and access:
http://192.168.107.25/ and login with your new user account. See if you can send an
email! If it does not work, well, what can I say...you followed the advice of a Linux
newbie.

Scripted sendmail
My scripts heavily reply upon the ability to send email notifications and this step will enable
that ability.
1. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
2. To configure the sendmail command to work with Zimbra, type the following:
Code:
update-alternatives --install /usr/sbin/sendmail mta-send
/opt/zimbra/postfix/sbin/sendmail 25

3. Test sendmail by typing the following and then check your admin email to see if it is
there:
Code:
sendmail -t{ENTER}
to:admin@mydomain.com{ENTER}
from:webmaster@mydomain.com{ENTER}
subject: Test from Ubuntu sendmail{ENTER}
{ENTER}
Testing 1-2-3{ENTER}
.{ENTER}

Delete Snapshots
Be sure to delete all snapshots when you are satisfied that you will no longer need to revert
your installation to any of the prior snapshots.

Zimbra and SSL Encryption
I do not see a reason not to use SSL, especially if your user accounts and passwords match
other systems such as Active Directory. A compromised email password can also
compromise your network in that case.
With that in mind, this is what I have done to make sure it is used at my location.
If you just installed Zimbra, the installation process created a self-signed certificate.
Step #1 - Enable SSL as the primary method of logging onto your server:
1. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
2. At the server console, type the following to convert webmail to use encrypted https
instead of http:
Code:
su - zimbra -c "zmtlsctl https"

3. For additional documentation, here is how you would switch back to non-SSL mode:
Code:
su - zimbra -c "zmtlsctl http"

4. For additional documentation, here is how you could use either SSL or non-SSL
mode:
Code:
su - zimbra -c "zmtlsctl mixed"

5. Type reboot to reboot the server for the HTTPS change to take effect.

Step #2 - Export the certificate for Windows.
The certificate on the Zimbra server cannot be directly used by Windows and needs to be
converted into a format that can be used. Do so using the following commands:
Code:
openssl x509 -in /opt/zimbra/ssl/zimbra/ca/ca.pem -out
/srv/samba/share/cacert.der -outform DER
chmod 0644 /srv/samba/share/cacert.der

Step #3 - Import the certificate on Windows.
For Windows machines, you might need to install the certificate manually to avoid Internet
Explorer, MS Outlook and Google Chrome issues with self-signed certificates.
Here are two methods for doing so.
Method A - Domain Group Policy
If you have a Windows domain, this is a very easy process to get all your machines to
automatically accept the self-signed certificate on your Zimbra server.
1.
2.
3.
4.
5.

On the domain controller, open Active Directory Users and Computers
Right-click on your domain and select Properties
Select the Group Policy tab
Select the Default Domain Policy and click the Edit button
Expand Computer Configuration --> Windows Settings --> Security Settings -->
Public Key Policies
6. Right-click on Trusted Root Certification Authorities and click Import
7. Import Wizard - Click Next
8. Type the path to the cacert.der from your Zimbra server or click Browse (if you
browse, you will need to change the file type to All Files in order to see the certificate
file) and then click Next
9. Select Place all certificates in the following store --> Trusted Root Certification
Authorities and click Next, Finish
10. The import was successful - Click OK
11. You should now see your mail server domain in the list. Example:
mail.mydomain.com
12. Close Group Policy Object Editor and any other windows you opened
Any Windows machine on your domain should now be able to open Internet Explorer and
visit your SSL-enabled mail server without complaining about the self-signed certificate.
Same goes for Outlook, Google Chrome and others. You may need to logout and log back in
for the policy to take effect on the PCs.
Method B - Manually Import the Certificate
If you are forced to manually touch each PC by hand, here is how you can install the
certificate (for Windows XP, Windows Vista or Windows 7)
1. Close Internet Explorer if it is open.
2. Click Start --> Run (or type in "Search programs and files" box on Windows 7) and
type mmc to load an empty Microsoft Management Console.
3. If you receive a security warning, click the positive acknowledgement button (actual
name varies all over the place).
4. From the menu, click File, Add / Remove Snap-In
5. Select Certificates and click the Add button
6. Select Computer account and click Next
7. Select Local computer and click Finish, OK
8. Expand Certificates, Trusted Root Certification Authorities and select the Certificates
container
9. Right-click on the Certificates container, and choose the All Tasks --> Import
10. Import Wizard - Click Next
11. Type 192.168.107.25sharecacert.der and click Next
12. Select Place all certificates in the following store --> Trusted Root Certification
Authorities and click Next, Finish
13. The import was successful - Click OK
14. Look in the list of certificates and you should see your domain such as
mail.mydomain.com
15. Close the console (do not bother saving the MMC when asked)

Step #4 - Update Your Certificate
As time goes by, the certificate that was created with your installation will expire (360 days
from install) and you will need to generate a new one.
1. At the login prompt, login with your administrator account (administrator /
myadminpass) and then type su and the root password (myrootpass)
2. Type the commands below to generate a new self-signed certificate:
Code:
/opt/zimbra/bin/zmcertmgr
/opt/zimbra/bin/zmcertmgr
/opt/zimbra/bin/zmcertmgr
/opt/zimbra/bin/zmcertmgr

createca -new
createcrt -new -days 365
deploycrt self
deployca

3. Check to see if the certificate was deployed to all services by typing
/opt/zimbra/bin/zmcertmgr viewdeployedcrt
4. Now go back through the above steps to export the new certificate and import into all
your PCs

Reference Article: Zimbra Wiki: Administration Console and CLI Certificate Tools
__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
#8 (permalink)
04-26-2012, 07:43 PM
LHammonds
Special Member

Posts: 138

Scripting

Scripting
Much of the solutions beyond this point involve scripts (programming snippets / automated
commands).
In particular, they are Bash Scripts. I chose this due to its popularity and the fact it comes
with Ubuntu. I try to make use of what comes with the system without requiring additional
software / services unless they really add to the bottom line such as decreasing the time it
takes for a process to run or to conserve storage and bandwidth usage.
When setting up a server and testing things out, there is typically very little concern for
procedures / process since much of the activity is exploration and experimentation as well as
not having an impact on production. However, once a server goes into production, processes
and procedures need to be in place to ensure the availability of the services being provided.
In regards to these scripts, they will be treated like any other program and will require being
tested, documented and go through a promotion process.
The ideal situation would involve 3 servers (for a single server setup). A test / development
server, a quality assurance staging server and the production server itself. If 3 servers cannot
be utilized, then it can still work well with 2 servers. Testing scripts / programs / restore on
the production server is not advisable and many times impractical...how can you test your
restore process / data periodically if you only have a production server?
The QA Staging server would be as close to production as possible. The server should be
setup in such a way that production backups are restored to this server which also tests and
validates the backup / restore process as well as maintains a close representation of the
production server to mitigate variable risk involved when testing new or modified programs
and upgrades.
The test / development server can serve as the QA server if absolutely necessary.
The directory structure and how scripts can import other scripts will be configured to
facilitate this process.
Example:
Directory path for scripts to import common variables, functions and server settings:
/var/scripts/common/
Directory path for production scripts: /var/scripts/prod/
Directory path for QA staging area scripts: /var/scripts/qa/
Directory path for test / development scripts: /var/scripts/test/
With a production and test servers on physically different machines, the "common" scripts
folder can be custom-tailored for that environment and allow for minimal changes to a script
when running on the test, QA or production server. This is similar to "normalizing" a
database. If you have a variable, path or function that is duplicated in multiple scripts,
consider pulling it out and placing it in the common folder. If ever you need to change who
receives the email reports, you only need to update a single script and all programs will use
the new reference from that point on.
Most of my scripts will import a file called "standard.conf" from the common script folder.
/var/scripts/common/standard.conf (contents of the file on the production server)
Code:
## Global Variables ##
TEMPDIR="/var/temp"
ZIMBRADIR="/opt/zimbra"
SHAREDIR="/srv/samba/share"
MYDOMAIN="mydomain.com"
ADMINEMAIL="admin@${MYDOMAIN}"
REPORTEMAIL="lhammonds@${MYDOMAIN}"
BACKUPDIR="/var/backup"
OFFSITEDIR="/mnt/backup"
OFFSITETESTFILE="${OFFSITEDIR}/online.txt"
ARCHIVEMETHOD="tar.7z"
## Choices are tar.7z or tgz
HOSTNAME="$(hostname -s)"
SCRIPTNAME="$0"
SCRIPTDIR="/var/scripts"
MAILFILE="${TEMPDIR}/mailfile.$$"
## Global Functions ##
function f_sendmail()
{
## Purpose: Send administrative email message.
## Parameter #1 = Subject
## Parameter #2 = Body
echo "From: ${ADMINEMAIL}" > ${MAILFILE}
echo "To: ${REPORTEMAIL}" >> ${MAILFILE}
echo "Subject: ${1}" >> ${MAILFILE}
echo "" >> ${MAILFILE}
echo -e "${2}" >> ${MAILFILE}
echo "" >> ${MAILFILE}
echo -e "nnServer: ${HOSTNAME}nProgram: ${SCRIPTNAME}nLog:
${LOGFILE}" >> ${MAILFILE}
sendmail -t < ${MAILFILE}
rm ${MAILFILE}
}
function f_sendusermail()
{
## Purpose: Send end-user email message.
## Parameter #1 = To
## Parameter #2 = Subject
## Parameter #3 = Body
echo "From: ${ADMINEMAIL}" > ${MAILFILE}
echo "To: ${1}" >> ${MAILFILE}
echo "Subject: ${2}" >> ${MAILFILE}
echo "" >> ${MAILFILE}
echo -e "${3}" >> ${MAILFILE}
sendmail -t < ${MAILFILE}
rm ${MAILFILE}
}
function f_mount()
{
## Mount the pre-configured Windows share folder.
## NOTE: The Windows share should have a file called "online.txt"
mount -t cifs //srv-backup/zimbra ${OFFSITEDIR} --options
nouser,rw,nofail,noatime,noexec,credentials=/etc/cifspw
}
function f_umount()
{
## Dismount the Windows share folder.
## NOTE: The unmounted folder should have a file called "offline.txt"
umount ${OFFSITEDIR}
}

/var/scripts/common/standard.conf (contents of the file on the test server)
Code:
## Global Variables ##
TEMPDIR="/tmp"
ZIMBRADIR="/opt/zimbra800"
SHAREDIR="/srv/samba/share"
MYDOMAIN="mytestdomain.com"
ADMINEMAIL="test1@${MYDOMAIN}"
REPORTEMAIL="test2@${MYDOMAIN}"
BACKUPDIR="/var/backup"
OFFSITEDIR="/mnt/fakedir"
OFFSITETESTFILE="${OFFSITEDIR}/online.txt"
ARCHIVEMETHOD="tar.7z"
## Choices are tar.7z or tgz
HOSTNAME="$(hostname -s)"
SCRIPTNAME="$0"
SCRIPTDIR="/var/scripts/"
MAILFILE="${TEMPDIR}/mailfile.$$"
## Global Functions ##
function f_sendmail()
{
## Purpose: Send administrative email message.
## Parameter #1 = Subject
## Parameter #2 = Body
echo "From: ${ADMINEMAIL}" > ${MAILFILE}
echo "To: ${REPORTEMAIL}" >> ${MAILFILE}
echo "Subject: ${1}" >> ${MAILFILE}
echo "" >> ${MAILFILE}
echo -e "${2}" >> ${MAILFILE}
echo "" >> ${MAILFILE}
echo -e "nnServer: ${HOSTNAME}nProgram: ${SCRIPTNAME}nLog:
${LOGFILE}" >> ${MAILFILE}
sendmail -t < ${MAILFILE}
rm ${MAILFILE}
}
function f_sendusermail()
{
## Purpose: Send end-user email message.
## Parameter #1 = To
## Parameter #2 = Subject
## Parameter #3 = Body
echo "From: ${ADMINEMAIL}" > ${MAILFILE}
echo "To: ${1}" >> ${MAILFILE}
echo "Subject: ${2}" >> ${MAILFILE}
echo "" >> ${MAILFILE}
echo -e "${3}" >> ${MAILFILE}
sendmail -t < ${MAILFILE}
rm ${MAILFILE}
}
function f_mount()
{
## Mount the pre-configured Windows share folder.
## NOTE: The Windows share should have a file called "online.txt"
mount -t cifs //mypc/zimbra ${OFFSITEDIR} --options
nouser,rw,nofail,noatime,noexec,credentials=/etc/cifspw
}
function f_umount()
{
## Dismount the Windows share folder.
## NOTE: The unmounted folder should have a file called "offline.txt"
umount ${OFFSITEDIR}
}

When receiving email notifications, the server name, script name and path will be included at
the bottom of the email every time. It will be readily apparent if the email was generated from
the test, qa or production server simply because of the location (even if test, qa and
production are all on the same server).
Here are the scripts to help automate the creation of this structure on the various servers
(would run all of them if all are the same box)
setup-script-prod.sh
Code:
#!/bin/bash
if [ ! -d /var/scripts/prod ]; then
mkdir -p /var/scripts/prod
fi
if [ ! -d /var/scripts/common ]; then
mkdir -p /var/scripts/common
fi
chown root:root /var/scripts
chown root:root /var/scripts/prod
chown root:root /var/scripts/common
chmod 0777 /var/scripts
chmod 0755 /var/scripts/prod
chmod 0755 /var/scripts/common

setup-script-qa.sh
Code:
#!/bin/bash
if [ ! -d /var/scripts/qa ]; then
mkdir -p /var/scripts/qa
fi
if [ ! -d /var/scripts/common ]; then
mkdir -p /var/scripts/common
fi
chown
chown
chown
chmod
chmod
chmod

root:root /var/scripts
root:root /var/scripts/qa
root:root /var/scripts/common
0777 /var/scripts
0777 /var/scripts/qa
0755 /var/scripts/common

setup-script-test.sh
Code:
#!/bin/bash
if [ ! -d /var/scripts/test ]; then
mkdir -p /var/scripts/test
fi
if [ ! -d /var/scripts/common ]; then
mkdir -p /var/scripts/common
fi
chown root:root /var/scripts
chown root:root /var/scripts/test
chown root:root /var/scripts/common
chmod 0777 /var/scripts
chmod 0777 /var/scripts/test
chmod 0777 /var/scripts/common

__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
Last edited by LHammonds; 05-05-2012 at 12:07 PM..
#9 (permalink)
04-26-2012, 07:48 PM
LHammonds
Special Member

Posts: 138

Keep Zimbra in Sync with Active Directory
For my scenario, I want mailboxes created automatically when I create an Active Directory
(AD) account. I do not want the mailbox to authenticate against AD though. To accomplish
this, two or three scripts will be created and setup to run on a regular basis.
The 1st script will be run on a Windows server and will create a comma-delimited (CSV) file
for all users who belong to a security group called "GRP_ZimbraEmail" which allows me to
selectively pick who is allowed to have a mailbox. The script will probably just run once per
day (after hours). The CSV file will be placed on Ubuntu's Samba share.
The 2nd script will be running on Ubuntu and checking for the input file very often (every
minute). It will then cycle through all the AD users and see which users do not have a
mailbox account and then create the mailbox using the supplied details.
export_zimbra_ad_users.vbs
Code:
Option Explicit
'****************************************
'** Name: export_zimbra_ad_users.vbs
'** Version: 1.1
'** Date: 2011-10-29
'** Author: LHammonds
'** Purpose: Export AD users to a comma-delimited file
'**
that are authorized to have a Zimbra mailbox.
'****************************************
'* Field #1 = LoginID
'* Field #2 = First Name
'* Field #3 = Middle Initial
'* Field #4 = Last Name
'* Field #5 = Full Name
'* Field #6 = Title
'* Field #7 = Description
'* Field #8 = Comments
'* Field #9 = Telephone
'* Field #10 = Home Phone
'* Field #11 = Mobile Phone
'* Field #12 = Fax Number
'* Field #13 = Pager
'* Field #14 = Company
'* Field #15 = Office
'* Field #16 = Street Address
'* Field #17 = PO Box
'* Field #18 = City
'* Field #19 = State
'* Field #20 = Postal Code
'* Field #21 = Country
'* Field #22 = Password Replacement Value
'* Field #23 = Unused (mainly to avoid the end-of-line character being read
into the last value)
'** NOTE: This could use a data cleanup routine that replaces all commas in
a **
'** variable with something else such as a period instead to avoid CSV
issues. **
Const
Const
Const
Const

ForAppending = 8
FilePath = "D:Reportsadlist.csv"
ZimbraSecurityGroup = "GRP_ZimbraEmail"
DefaultPassword = "ChangeThisPassword"

Dim objRootDSE, strDNC, objDomain, objFSO, objFile
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNC = objRootDSE.Get("DefaultNamingContext")
Set objDomain = GetObject("LDAP://" & strDNC)
'** Create / Overwrite the export file. **
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile(FilePath)
objFile.Close
Set objFile = Nothing
Call TrollTheFolders(objDomain)
Sub TrollTheFolders(pobjDomain)
'** Function: Traverse the AD structure to find users wherever they may
reside. **
'**
The trick is that this function is called recursively in
order to **
'**
inspect every sub-folder that may contain user accounts.
**
Dim lobjFile, lobjFSO, lobjMember, lstrLine, lblnInZimbraGroup
Dim lstrSamAccountName, lstrFirstName, lstrInitials, lstrLastName
Dim lstrFullName, lstrTitle, lstrDescription, lstrComment
Dim lstrTelephoneNumber, lstrHomePhone, lstrMobile, lstrFaxNumber,
lstrPager
Dim lstrCompany, lstrOffice, lstrStreetAddress, lstrPostOfficeBox
Dim lstrCity, lstrState, lstrPostalCode, lstrCountry, lstrPassword
Dim lcolGroups, lobjGroup, lstrTemp
For Each lobjMember In pobjDomain
'** Examine each object but process only "user" objects. **
If lobjMember.Class = "user" Then
Set lobjFile = objFSO.OpenTextFile (FilePath, ForAppending, True)
If Not (isempty(lobjMember.samAccountName)) Then lstrSamAccountName =
lobjMember.samAccountName Else lstrSamAccountName = "" End If
If Not (isempty(lobjMember.GivenName)) Then lstrFirstName =
lobjMember.GivenName Else lstrFirstName = "" End If
If Not (isempty(lobjMember.initials)) Then lstrInitials =
lobjMember.initials Else lstrInitials = "" End If
If Not (isempty(lobjMember.sn)) Then lstrLastname = lobjMember.sn
Else lstrLastName = "" End If
If Not (isempty(lobjMember.CN)) Then lstrFullName = lobjMember.CN
Else lstrFullName = "" End If
If Not (isempty(lobjMember.title)) Then lstrTitle = lobjMember.title
Else lstrTitle = "" End If
If Not (isempty(lobjMember.Description)) Then lstrDescription =
lobjMember.Description Else lstrDescription = "" End If
If Not (isempty(lobjMember.comment)) Then lstrComment =
lobjMember.comment Else lstrComment = "" End If
If Not (isempty(lobjMember.telephoneNumber)) Then lstrTelephoneNumber
= lobjMember.telephoneNumber Else lstrTelephoneNumber = "" End If
If Not (isempty(lobjMember.homePhone)) Then lstrHomePhone =
lobjMember.homePhone Else lstrHomePhone = "" End If
If Not (isempty(lobjMember.mobile)) Then lstrMobile =
lobjMember.mobile Else lstrMobile = "" End If
If Not (isempty(lobjMember.otherFacsimileTelephoneNumber)) Then
lstrFaxNumber = lobjMember.otherFacsimileTelephoneNumber Else lstrFaxNumber
= "" End If
If Not (isempty(lobjMember.pager)) Then lstrPager = lobjMember.pager
Else lstrPager = "" End If
If Not (isempty(lobjMember.company)) Then lstrCompany =
lobjMember.company Else lstrCompany = "" End If
If Not (isempty(lobjMember.physicalDeliveryOfficeName)) Then
lstrOffice = lobjMember.physicalDeliveryOfficeName Else lstrOffice = "" End
If
If Not (isempty(lobjMember.streetAddress)) Then lstrStreetAddress =
lobjMember.streetAddress Else lstrStreetAddress = "" End If
If Not (isempty(lobjMember.postOfficeBox)) Then lstrPostOfficeBox =
lobjMember.postOfficeBox Else lstrPostOfficeBox = "" End If
If Not (isempty(lobjMember.l)) Then lstrCity = lobjMember.l Else
lstrCity = "" End If
If Not (isempty(lobjMember.st)) Then lstrState = lobjMember.st Else
lstrState = "" End If
If Not (isempty(lobjMember.postalCode)) Then lstrPostalCode =
lobjMember.postalCode Else lstrPostalCode = "" End If
If Not (isempty(lobjMember.countryCode)) Then lstrCountry =
lobjMember.countryCode Else lstrCountry = "" End If
lstrPassword = DefaultPassword
lblnInZimbraGroup = 0
For Each lobjGroup in lobjMember.Groups
'** See if this member belongs to the group that allows Zimbra
mailboxes **
If LCase(lobjGroup.cn) = LCase(ZimbraSecurityGroup) Then
lblnInZimbraGroup = 1
End If
Next
If lblnInZimbraGroup = 1 Then
'** Member is associated to the Zimbra Email group and thus allowed
to have a Zimbra mailbox. **
lstrLine = lstrSamAccountName & "," & lstrFirstName & "," &
lstrInitials & "," & lstrLastName & "," & lstrFullName & "," &_
lstrTitle & "," & lstrDescription & "," & lstrComment & "," &
lstrTelephoneNumber & "," & lstrHomePhone & "," & lstrMobile & "," &_
lstrFaxNumber & "," & lstrPager & "," & lstrCompany & "," &
lstrOffice & "," & lstrStreetAddress & "," & lstrPostOfficeBox & "," &_
lstrCity & "," & lstrState & "," & lstrPostalCode & "," &
lstrCountry & "," & lstrPassword & ",unused"
lobjFile.WriteLine(lstrLine)
End If
lobjFile.Close
Set lobjFile = Nothing
End If
If lobjMember.Class = "organizationalUnit" or lobjMember.Class =
"container" Then
'** Recurse further down to find the users. **
TrollTheFolders(lobjMember)
End If
Next
End Sub

Sample adlist.csv
Code:
mmouse,Mickey,,Mouse,Mickey Mouse,,Lab Assistant,,,,,,800-8675309,,,,,,,,0,ChangeThisPassword,unused
jdirt,Joe,,Dirt,Joe Dirt,Chief Information Officer,Chief Information
Officer,,800-555-5555,,,,,ABC,Information Systems,404 Hollywood
Street,,Hollywood,CA,90210,840,ChangeThisPassword,unused
ddiggler,Dirk,,Diggler,Dirk Diggler,Database Administrator,IS-Database
Administrator,,800-555-0404,800-789-1234,888-111-2222,,,,Information
Systems,404 Cowboy Country
Road,,Hickville,TX,77501,840,ChangeThisPassword,unused
jdoe,John,,Doe,John Doe,System Analyst,IS-Telco Systems Analyst,,800-9998888,,,,,,Information Systems,666 Gov
Road,,Washington,WA,10110,840,ChangeThisPassword,unused

import-ad.sh
Code:
#!/bin/bash
#############################################
## Name
: import-ad.sh
## Version
: 1.2
## Date
: 2011-11-02
## Author
: LHammonds
## Purpose
: Add mailbox accounts for AD users that have none.
## Compatibility : Verified on Ubuntu Server 10.04.3 - 10.04.4 LTS, Zimbra
7.1.2 - 7.2.0 OSE
## Requirements : Zimbra must be online, must be run as root user.
## Run Frequency : Run very frequently (every minute)
## Exit Codes
:
##
0 = Success
##
1 = Failure
################ CHANGE LOG #################
## DATE
WHO WHAT WAS CHANGED
## ---------- --- ---------------------------## 2011-10-11 LTH Created script.
## 2011-10-29 LTH Better logging, mail support, bug fixes.
## 2011-11-02 LTH Moved standard variables/functions to external file.
#############################################
## Import standard variables and functions. ##
source /var/scripts/common/standard.conf
LOGFILE="${TEMPDIR}/import-ad.log"
MAILFILE="${TEMPDIR}/import-ad-mail.$$"
ADLISTORG="${SHAREDIR}/adlist.csv"
ADLISTNEW="${TEMPDIR}/import-ad-adlist.$$"
ZMUSERS="${TEMPDIR}/import-ad-zmuserlist.$$"
ZMCMD="${TEMPDIR}/import-ad-zmcmd.$$"
NEWUSERS=""
RETURNVALUE=0
## Temporarily change the default field separator to a comma. #
OLDIFS="${IFS}"
IFS=","
## If the Active Directory user list file is not found, exit the script. #
if [ ! -f ${ADLISTORG} ]; then
## No file to process. Exit script.
exit 0
fi
echo "`date +%Y-%m-%d_%H:%M:%S` - Active Directory file found! Import
process started." >> ${LOGFILE}
## Create files and set permissions for only the root user. #
touch ${ZMCMD}
touch ${ZMUSERS}
chmod 0600 ${ZMCMD}
chmod 0600 ${ZMUSERS}
## Take ownership and set permissions for only the root user. #
chown root:root ${ADLISTORG}
chmod 0400 ${ADLISTORG}
## Move the file to a working folder. #
mv ${ADLISTORG} ${ADLISTNEW}
## Create a list of users in Zimbra for the specified domain. #
${ZIMBRADIR}/bin/zmprov -l getAllAccounts ${MYDOMAIN} > ${ZMUSERS}
## Loop through the Active Directory user list. #
while read -a ADLINE ; do
## Slot 0 = UserID
## Slot 1 = First Name (GivenName)
## Slot 2 = Initials
## Slot 3 = Last Name (sn)
## Slot 4 = Full Name (CN)
## Slot 5 = Title
## Slot 6 = Description
## Slot 7 = Comment
## Slot 8 = Telephone / Work Number
## Slot 9 = Home Phone
## Slot 10 = Mobile Phone
## Slot 11 = Fax Number (facsimileTelephoneNumber)
## Slot 12 = Pager
## Slot 13 = Company
## Slot 14 = Office (physicalDeliveryOfficeName)
## Slot 15 = Street Address
## Slot 16 = Post Office Box
## Slot 17 = City (l)
## Slot 18 = State (st)
## Slot 19 = Postal Code
## Slot 20 = Country Code (co)
## Slot 21 = Password
## Set the "Found Match" variable to false #
FOUND=0
## Loop through the Zimbra User List. #
while read -a ZMLINE ; do
## Convert Usernames to lower case. #
ZMUSERID=${ZMLINE[0],,}
ADUSERID=${ADLINE[0],,}
## Add domain address to the end of the AD Username #
ADUSERID=${ADUSERID}"@"${MYDOMAIN}
## Compare the lowercase AD username to the lower case Zimbra username.
#
if [ ${ADUSERID} == ${ZMUSERID} ]; then
## Match found. Exit this while loop. #
FOUND=1
break
fi
done < ${ZMUSERS}
if [ ${FOUND} -eq 0 ]; then
## We have an AD user that does not have a Zimbra mailbox. #
NEWUSERS="${NEWUSERS}${ADLINE[0]}@${MYDOMAIN}n"
echo "`date +%Y-%m-%d_%H:%M:%S` --- Adding new user:
${ADLINE[0]}@${MYDOMAIN}" >> ${LOGFILE}
echo "createAccount ${ADLINE[0]}@${MYDOMAIN} "${ADLINE[21]}" gn
"${ADLINE[1]}" initials "${ADLINE[2]}" sn "${ADLINE[3]}" cn
"${ADLINE[4]}" title "${ADLINE[5]}" description "${ADLINE[6]}"
zimbraNotes "${ADLINE[7]}" telephoneNumber "${ADLINE[8]}" homePhone
"${ADLINE[9]}" mobile "${ADLINE[10]}" facsimileTelephoneNumber
"${ADLINE[11]}" pager "${ADLINE[12]}" company "${ADLINE[13]}"
physicalDeliveryOfficeName "${ADLINE[14]}" street "${ADLINE[15]}"
postOfficeBox "${ADLINE[16]}" l "${ADLINE[17]}" st "${ADLINE[18]}"
postalCode "${ADLINE[19]}" co "${ADLINE[20]}"">> ${ZMCMD}
fi
done < ${ADLISTNEW}
## If the Zimbra command file is not empty, we need to process it. #
if [ -s ${ZMCMD} ]; then
${ZIMBRADIR}/bin/zmprov < ${ZMCMD} 1>/dev/null 2>&1
RETURNVALUE=$?
if [ ${RETURNVALUE} -ne 0 ]; then
## Something went wrong with the mailbox creation.
## This error should notify administrators to the problem.
echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: zmprov reported the
following error: ${RETURNVALUE}" >> ${LOGFILE}
echo "`date +%Y-%m-%d_%H:%M:%S` - Import aborted. EXIT CODE = 1" >>
${LOGFILE}
f_sendmail "Zimbra Active Directory Import" "ERROR: zmprov reported the
following error: ${RETURNVALUE}nnRemaining temporary
files:n${ZMUSERS}n${ZMCMD}n${ADLISTNEW}n"
exit 1
fi
## Send email notification of the new users added to Zimbra. #
## NOTE: To be 100% sure about this, we could loop through the users #
##
and verify that they now have Zimbra mailboxes. #
f_sendmail "Zimbra Notification - New Users" "The following users were
added to Zimbra:nn${NEWUSERS}"
else
## There were no new users to process. #
echo "`date +%Y-%m-%d_%H:%M:%S` --- No new users to import." >>
${LOGFILE}
fi
echo "`date +%Y-%m-%d_%H:%M:%S` - Active Directory import completed." >>
${LOGFILE}
## Restore the default field separator value. #
IFS="${OLDIFS}"
##
rm
rm
rm

Remove temporary files. #
${ZMUSERS}
${ZMCMD}
${ADLISTNEW}

Sample email when new mailboxes are created:
Code:
Subject: Zimbra Notification - New Users
The following users were added to Zimbra:
ddiggler@mydomain.com
jdoe@mydomain.com
jsmith@mydomain.com
lhammonds@mydomain.com
mmouse@mydomain.com
Server: mail
Program: /var/scripts/prod/import-ad.sh
Log: /var/temp/import-ad.log

Here is a sample log file (NOTE: There are no entries if no file is found):
Code:
2011-10-29_17:06:49
2011-10-29_17:06:52
2011-10-29_17:06:53
2011-10-29_17:06:53
2011-10-29_17:06:53
2011-10-29_17:06:53

- Active Directory file found! Import process started.
--- Adding new user: ddiggler@mydomain.com
--- Adding new user: jdoe@mydomain.com
--- Adding new user: jsmith@mydomain.com
--- Adding new user: lhammonds@mydomain.com
--- Adding new user: mmouse@mydomain.com
2011-10-29_17:06:56
2011-10-29_17:07:29
2011-10-29_17:07:32
2011-10-29_17:07:32

- Active Directory import completed.
- Active Directory file found! Import process started.
--- No new users to import.
- Active Directory import completed.

If you keep a database of all your user's IDs and passwords, you could export that
information to the Linux box and have it safely tucked away and used in-between the AD
Export and AD Import process. It could run through the AD user list and replace the default
password with their existing password making it operate seamlessly within the environment.
If user passwords are unknown, the process would be to let the individual know their mailbox
was created with a standard password and that they need to login and change it ASAP.
Reference Articles:
zmprov command-line documentation
Bash Guide

NOTE: If you like this solution, you might also want to review the modified version by digidt
in my older thread.
__________________
Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile
(more info here)
#10 (permalink)
04-26-2012, 07:50 PM
LHammonds
Special Member

Posts: 138

Global Address List for iPhones

Global Address List for iPhones
I have a working solution in place for our iPhone users to access the Internal Global Address
List (GAL) when they start a new email message and click the "To" button to show a list of
all contacts in our company (not just personal contacts).
Normally, you will only get a list of contacts in your personal folder. I have tried various
ways to get this to work such as sharing the _InternalGAL folder but could not get anything
to work well. I certainly do not want to give my users the credentials to the galsync account
(which is my admin account).
This method uses a service account (dummy mailbox) to hold a copy of the GAL. Each
iPhone user then adds an additional CardDAV account and enters the shared account's
details.
For this example, I created a mailbox called "addresslist@mydomain.com" and then logged
into that account and shared the contacts folder as "Public" for anyone to access.
Next, login to the admin console, expand Configuration --> Domains and click on
mydomain.com. Click the Configure GAL button. Set the following and click Next, Finish:
GAL mode: Internal
Most results returned by GAL search: 250
Use GAL Sync account (recommended): Check
GAL sync account name: admin@mydomain.com (or whatever galsync account you want)
Datasource name for internal GAL: InternalGAL
Internal GAL polling interval: 1 days
Next, force the initial sync by typing the following at the Ubuntu console as the root user:
Code:
su - zimbra -c "zmgsautil forceSync -a admin@mydomain.com -n InternalGAL"

If you login to the web mail client and login with the galsync (admin) account, you should
see the "_InternalGAL" folder under the Address Book tab and it should be populated with
your internal users.
Before the account can be backed up with the script below, the services need to be restarted.
Code:
/etc/init.d/zimbra stop
/etc/init.d/zimbra start

Now setup the script below to run on a regular schedule which will backup the GAL Sync's
"_InternalGAL" folder to an archive. It will then extract the archive and change references of
"_InternalGAL" to "Contacts" in all files so it can be restored in a folder that the iPhone will
recognize. Then it is re-packed into an archive and restored to the "addresslist" account which
completely replaces whatever is in the "Contacts" folder with the updated list. As an
additional step, it will delete specific addresses which are not desired to show up in the global
list.
Also note that this is not necessary on the Pro Network Edition which has an iPhone sync
utility.
gal-sync.sh
Code:
#!/bin/bash
#############################################
## Name
: gal-sync.sh
## Version
: 1.1
## Date
: 2011-11-02
## Author
: LHammonds
## Compatibility : Ubuntu Server 10.04.3 - 10.04.4 LTS, Zimbra 7.1.3 7.2.0 OSE
## Requirements : Zimbra must be online, must be run as root user.
## Purpose
: Expose Internal GAL (Global Address List) for use on
iPhones
## Run Frequency : Once per day (after hours preferable but not necessary)
## Exit Codes
: (if multiple errors, value is the addition of codes)
##
0 = success
##
1 = security failure
##
2 = zmmailbox getRestURL failure
##
4 = zmmailbox postRestURL failure
##
8 = zmmailbox getAllContacts failure
##
16 = tar extraction failure
##
32 = tar creation failure
################# CHANGE LOG #################
## DATE
WHO WHAT WAS CHANGED
## ---------- --- ---------------------------## 2011-10-28 LTH Created script.
## 2011-10-31 LTH Added check for root ID.
## 2011-11-02 LTH Moved standard variables / functions to external file.
## NOTE: Should add detection of address list account.
##############################################
## Import common variables and functions. ##
source /var/scripts/common/standard.conf
GALSYNCACCT="admin@${MYDOMAIN}"
PUBLICGALACCT="addresslist@${MYDOMAIN}"
EXCEPTIONS="addresslist@${MYDOMAIN};admin@${MYDOMAIN};test@${MYDOMAIN};test
2@${MYDOMAIN}"
GALSYNCDIR="${TEMPDIR}/galsync"
LOGFILE="${TEMPDIR}/gal-sync.log"
CONTACTFILE="${TEMPDIR}/gal-sync-contact.$$"
GALARCHIVE1="galsync1.tgz"
GALARCHIVE2="galsync2.tgz"
CONTACTNUMDEL=0
CONTACTNUMALL=0
RETURNVALUE=0
ERRORFLAG=0
#######################################
##
FUNCTIONS
##
#######################################
function f_cleanup()
{
## Purpose: Cleanup files and folders used by the script.
if [ -d ${GALSYNCDIR} ]; then
rm -rf ${GALSYNCDIR}
fi
if [ -f ${TEMPDIR}/${GALARCHIVE1} ]; then
rm ${TEMPDIR}/${GALARCHIVE1}
fi
if [ -f ${TEMPDIR}/${GALARCHIVE2} ]; then
rm ${TEMPDIR}/${GALARCHIVE2}
fi
if [ -f ${CONTACTFILE} ]; then
rm ${CONTACTFILE}
fi
}
function f_emergencyexit()
{
## Purpose: Exit script as cleanly as possible.
## Parameter #1 = Error Code.
f_cleanup
f_sendmail "Zimbra iPhone GAL Sync Error" "EXIT CODE = ${1}"
echo "`date +%Y-%m-%d_%H:%M:%S` - GAL Sync aborted. EXIT CODE: ${1}" >>
${LOGFILE}
## Write script name and error code to the system log.
logger "${SCRIPTNAME}: ERROR CODE = ${1}"
exit $1
}
#######################################
##
MAIN PROGRAM
##
#######################################
echo "`date +%Y-%m-%d_%H:%M:%S` - GAL Sync started." >> ${LOGFILE}
## Requirement Check: Script must run as root user.
if [ "$(id -u)" != "0" ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo "`date +%Y-%m-%d_%H:%M:%S` - GAL Sync aborted. ERROR: Root user
required." >> ${LOGFILE}
ERRORFLAG=$((${ERRORFLAG} + 1))
f_emergencyexit ${ERRORFLAG}
fi
## Backup the global address listing.
${ZIMBRADIR}/bin/zmmailbox -z -m ${GALSYNCACCT} getRestURL
"/_InternalGAL?fmt=tgz" > ${TEMPDIR}/${GALARCHIVE1}
RETURNVALUE=$?
if [ ${RETURNVALUE} -ne 0 ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: ${ZIMBRADIR}/bin/zmmailbox -z
-m ${GALSYNCACCT} getRestURL '/_InternalGAL?fmt=tgz'" >> ${LOGFILE}
echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >>
${LOGFILE}
ERRORFLAG=$((${ERRORFLAG} + 2))
f_emergencyexit ${ERRORFLAG}
fi
## Prepare the extraction folder and set appropriate permissions.
mkdir -p ${GALSYNCDIR}
chmod 0600 ${GALSYNCDIR}
## Extract the archive to modify its contents.
tar -xf ${TEMPDIR}/${GALARCHIVE1} -C ${GALSYNCDIR} 1>/dev/null 2>&1
RETURNVALUE=$?
if [ ${RETURNVALUE} -ne 0 ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: tar -xf
${TEMPDIR}/${GALARCHIVE1} -C ${GALSYNCDIR}" >> ${LOGFILE}
echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >>
${LOGFILE}
ERRORFLAG=$((${ERRORFLAG} + 16))
f_emergencyexit ${ERRORFLAG}
fi
## Search and replace all meta data occurances of "_InternalGAL" with
"Contacts"
## This will allow the contacts to be restored to the "Contacts" folder.
sed -i 's/_InternalGAL/Contacts/g' ${GALSYNCDIR}/*.meta
sed -i 's/_InternalGAL/Contacts/g' ${GALSYNCDIR}/_InternalGAL/*.meta
## Count the number of meta files (contacts) in the GAL folder.
CONTACTNUMALL=`ls -1 ${GALSYNCDIR}/_InternalGAL/*.meta | wc -l`
## Create a new archive with the modified data.
tar -czf ${TEMPDIR}/${GALARCHIVE2} ${GALSYNCDIR} 1>/dev/null 2>&1
RETURNVALUE=$?
if [ ${RETURNVALUE} -ne 0 ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: tar -czf
${TEMPDIR}/${GALARCHIVE2} ${GALSYNCDIR}" >> ${LOGFILE}
echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >>
${LOGFILE}
ERRORFLAG=$((${ERRORFLAG} + 32))
f_emergencyexit ${ERRORFLAG}
fi
## Replace contacts in the iPhone GAL account.
${ZIMBRADIR}/bin/zmmailbox -z -m ${PUBLICGALACCT} postRestURL
"//?fmt=tgz&resolve=reset" ${TEMPDIR}/${GALARCHIVE2}
RETURNVALUE=$?
if [ ${RETURNVALUE} -ne 0 ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: ${ZIMBRADIR}/bin/zmmailbox -z
-m ${PUBLICGALACCT} postRestURL '//?fmt=tgz&resolve=reset'" >> ${LOGFILE}
echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >>
${LOGFILE}
ERRORFLAG=$((${ERRORFLAG} + 4))
f_emergencyexit ${ERRORFLAG}
fi
## Export all contacts to a working file to determine which contacts to
remove.
${ZIMBRADIR}/bin/zmmailbox -z -m ${PUBLICGALACCT} getAllContacts >
${CONTACTFILE}
RETURNVALUE=$?
if [ ${RETURNVALUE} -ne 0 ]; then
## FATAL ERROR DETECTED: Document problem and terminate script.
echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: ${ZIMBRADIR}/bin/zmmailbox -z
-m ${PUBLICGALACCT} getAllContacts" >> ${LOGFILE}
echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >>
${LOGFILE}
ERRORFLAG=$((${ERRORFLAG} + 8))
f_emergencyexit ${ERRORFLAG}
fi
## Obtain list of Contact IDs with matching email addresses in the
exception list.
while read LINEID LINEVALUE; do
if [ "${LINEID}" = "Id:" ]; then
CURRID=${LINEVALUE}
fi
if [ "${LINEID}" = "email:" ]; then
## Determine if this is an email address that we are looking for.
if `echo ${EXCEPTIONS} | grep -q "${LINEVALUE}"`
then
## Found a contact to remove from the address book.
## Verify that the contact ID is an integer.
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure
L hammonds adventure

Mais conteúdo relacionado

Mais procurados

Installation of linux mint 18 sarah
Installation of linux mint 18 sarahInstallation of linux mint 18 sarah
Installation of linux mint 18 sarahAdich3
 
Install ubuntu
Install ubuntuInstall ubuntu
Install ubuntupramoddps
 
Oracle VM3: Virtuelle Maschinen per Script erstellen
Oracle VM3: Virtuelle Maschinen per Script erstellenOracle VM3: Virtuelle Maschinen per Script erstellen
Oracle VM3: Virtuelle Maschinen per Script erstellenTrivadis
 
Quick Starter Guide For Lotus Foundations Trial
Quick Starter Guide For Lotus Foundations TrialQuick Starter Guide For Lotus Foundations Trial
Quick Starter Guide For Lotus Foundations TrialChris Sparshott
 
BOOTABLE OPERATING SYSTEM PPT
BOOTABLE OPERATING SYSTEM PPTBOOTABLE OPERATING SYSTEM PPT
BOOTABLE OPERATING SYSTEM PPTShahzeb Pirzada
 
Using cobbler in a not so small environment 1.77
Using cobbler in a not so small environment 1.77Using cobbler in a not so small environment 1.77
Using cobbler in a not so small environment 1.77chhorn
 
Windows Server "10": что нового в кластеризации
Windows Server "10": что нового в кластеризацииWindows Server "10": что нового в кластеризации
Windows Server "10": что нового в кластеризацииВиталий Стародубцев
 
Network File System (NFS)
Network File System (NFS)Network File System (NFS)
Network File System (NFS)abdullah roomi
 
Deployment Strategies
Deployment StrategiesDeployment Strategies
Deployment StrategiesMongoDB
 
Introduction, Installation Operating System and Application
Introduction, Installation Operating System and ApplicationIntroduction, Installation Operating System and Application
Introduction, Installation Operating System and ApplicationVichhaiy Serey
 
Vista Report Card
Vista Report CardVista Report Card
Vista Report CardJoel May
 
Windows Vista- a Report Card
Windows Vista- a Report CardWindows Vista- a Report Card
Windows Vista- a Report Cardschroedinger
 
BP108 Admin for the Developer -- Build and Secure Your Own IBM Lotus Domino S...
BP108 Admin for the Developer -- Build and Secure Your Own IBM Lotus Domino S...BP108 Admin for the Developer -- Build and Secure Your Own IBM Lotus Domino S...
BP108 Admin for the Developer -- Build and Secure Your Own IBM Lotus Domino S...NerdGirlJess
 
Tech X Virtualization Tips
Tech X Virtualization TipsTech X Virtualization Tips
Tech X Virtualization TipsYoussef EL HADJ
 

Mais procurados (20)

Installation of linux mint 18 sarah
Installation of linux mint 18 sarahInstallation of linux mint 18 sarah
Installation of linux mint 18 sarah
 
Install ubuntu
Install ubuntuInstall ubuntu
Install ubuntu
 
Oracle VM3: Virtuelle Maschinen per Script erstellen
Oracle VM3: Virtuelle Maschinen per Script erstellenOracle VM3: Virtuelle Maschinen per Script erstellen
Oracle VM3: Virtuelle Maschinen per Script erstellen
 
Quick Starter Guide For Lotus Foundations Trial
Quick Starter Guide For Lotus Foundations TrialQuick Starter Guide For Lotus Foundations Trial
Quick Starter Guide For Lotus Foundations Trial
 
BOOTABLE OPERATING SYSTEM PPT
BOOTABLE OPERATING SYSTEM PPTBOOTABLE OPERATING SYSTEM PPT
BOOTABLE OPERATING SYSTEM PPT
 
vSphere
vSpherevSphere
vSphere
 
Using cobbler in a not so small environment 1.77
Using cobbler in a not so small environment 1.77Using cobbler in a not so small environment 1.77
Using cobbler in a not so small environment 1.77
 
ZFS Talk Part 1
ZFS Talk Part 1ZFS Talk Part 1
ZFS Talk Part 1
 
Windows Server "10": что нового в кластеризации
Windows Server "10": что нового в кластеризацииWindows Server "10": что нового в кластеризации
Windows Server "10": что нового в кластеризации
 
Network File System (NFS)
Network File System (NFS)Network File System (NFS)
Network File System (NFS)
 
Cobbler, Func and Puppet: Tools for Large Scale Environments
Cobbler, Func and Puppet: Tools for Large Scale EnvironmentsCobbler, Func and Puppet: Tools for Large Scale Environments
Cobbler, Func and Puppet: Tools for Large Scale Environments
 
Deployment Strategies
Deployment StrategiesDeployment Strategies
Deployment Strategies
 
Introduction, Installation Operating System and Application
Introduction, Installation Operating System and ApplicationIntroduction, Installation Operating System and Application
Introduction, Installation Operating System and Application
 
Azbox me
Azbox meAzbox me
Azbox me
 
Vista Report Card
Vista Report CardVista Report Card
Vista Report Card
 
Good virtual machines
Good virtual machinesGood virtual machines
Good virtual machines
 
Windows Vista- a Report Card
Windows Vista- a Report CardWindows Vista- a Report Card
Windows Vista- a Report Card
 
BP108 Admin for the Developer -- Build and Secure Your Own IBM Lotus Domino S...
BP108 Admin for the Developer -- Build and Secure Your Own IBM Lotus Domino S...BP108 Admin for the Developer -- Build and Secure Your Own IBM Lotus Domino S...
BP108 Admin for the Developer -- Build and Secure Your Own IBM Lotus Domino S...
 
Tech X Virtualization Tips
Tech X Virtualization TipsTech X Virtualization Tips
Tech X Virtualization Tips
 
Virtualization.pdf
Virtualization.pdfVirtualization.pdf
Virtualization.pdf
 

Semelhante a L hammonds adventure

Connections install in 45 mins
Connections install in 45 minsConnections install in 45 mins
Connections install in 45 minsSharon James
 
Intro To Linux
Intro To LinuxIntro To Linux
Intro To Linuxtechlug
 
Installing and Configuring Domino 10 on CentOS 7
Installing and Configuring Domino 10 on CentOS 7Installing and Configuring Domino 10 on CentOS 7
Installing and Configuring Domino 10 on CentOS 7Devin Olson
 
Dru lavigne servers-tutorial
Dru lavigne servers-tutorialDru lavigne servers-tutorial
Dru lavigne servers-tutorialDru Lavigne
 
Centralized Fog Server with OpenLDAP
Centralized Fog Server with OpenLDAP Centralized Fog Server with OpenLDAP
Centralized Fog Server with OpenLDAP tare
 
Practical Introduction To Linux
Practical Introduction To LinuxPractical Introduction To Linux
Practical Introduction To LinuxZeeshan Rizvi
 
Tutorial CentOS 5 untuk Webhosting
Tutorial CentOS 5 untuk WebhostingTutorial CentOS 5 untuk Webhosting
Tutorial CentOS 5 untuk WebhostingBeni Krisbiantoro
 
Classroom ltsp configuration
Classroom ltsp configurationClassroom ltsp configuration
Classroom ltsp configurationbillmulyanto
 
Day 6 ubuntu boot camp
Day 6 ubuntu boot campDay 6 ubuntu boot camp
Day 6 ubuntu boot campDarlene Parker
 
Reformat PPT.pptx
Reformat PPT.pptxReformat PPT.pptx
Reformat PPT.pptxLINDYLGERAL
 
Day 5 ubuntu boot camp
Day 5 ubuntu boot campDay 5 ubuntu boot camp
Day 5 ubuntu boot campDarlene Parker
 

Semelhante a L hammonds adventure (20)

Connections install in 45 mins
Connections install in 45 minsConnections install in 45 mins
Connections install in 45 mins
 
Intro To Linux
Intro To LinuxIntro To Linux
Intro To Linux
 
Installing and Configuring Domino 10 on CentOS 7
Installing and Configuring Domino 10 on CentOS 7Installing and Configuring Domino 10 on CentOS 7
Installing and Configuring Domino 10 on CentOS 7
 
Dru lavigne servers-tutorial
Dru lavigne servers-tutorialDru lavigne servers-tutorial
Dru lavigne servers-tutorial
 
Centralized Fog Server with OpenLDAP
Centralized Fog Server with OpenLDAP Centralized Fog Server with OpenLDAP
Centralized Fog Server with OpenLDAP
 
Ubuntu server guide
Ubuntu server guideUbuntu server guide
Ubuntu server guide
 
Guide koha
Guide kohaGuide koha
Guide koha
 
Practical Introduction To Linux
Practical Introduction To LinuxPractical Introduction To Linux
Practical Introduction To Linux
 
Tutorial CentOS 5 untuk Webhosting
Tutorial CentOS 5 untuk WebhostingTutorial CentOS 5 untuk Webhosting
Tutorial CentOS 5 untuk Webhosting
 
Windows 2003 Server
Windows 2003 ServerWindows 2003 Server
Windows 2003 Server
 
Classroom ltsp configuration
Classroom ltsp configurationClassroom ltsp configuration
Classroom ltsp configuration
 
Xen time machine
Xen time machineXen time machine
Xen time machine
 
.ppt
.ppt.ppt
.ppt
 
Day 6 ubuntu boot camp
Day 6 ubuntu boot campDay 6 ubuntu boot camp
Day 6 ubuntu boot camp
 
Why linux sucks
Why linux sucksWhy linux sucks
Why linux sucks
 
Edubooktraining
EdubooktrainingEdubooktraining
Edubooktraining
 
Apache ssl
Apache ssl Apache ssl
Apache ssl
 
Linux vs windows
Linux vs windowsLinux vs windows
Linux vs windows
 
Reformat PPT.pptx
Reformat PPT.pptxReformat PPT.pptx
Reformat PPT.pptx
 
Day 5 ubuntu boot camp
Day 5 ubuntu boot campDay 5 ubuntu boot camp
Day 5 ubuntu boot camp
 

Mais de Muhamad Fauzi

Kurikulum smk farmasi
Kurikulum smk farmasiKurikulum smk farmasi
Kurikulum smk farmasiMuhamad Fauzi
 
Bab ii profil dan pengembangan renop 2013 2014
Bab ii profil dan pengembangan renop 2013 2014Bab ii profil dan pengembangan renop 2013 2014
Bab ii profil dan pengembangan renop 2013 2014Muhamad Fauzi
 
Formulir5 stikes analis_kesehatan_diii
Formulir5 stikes analis_kesehatan_diiiFormulir5 stikes analis_kesehatan_diii
Formulir5 stikes analis_kesehatan_diiiMuhamad Fauzi
 
Buku 7 pedoman asesmen lapangan s2
Buku 7 pedoman asesmen lapangan s2Buku 7 pedoman asesmen lapangan s2
Buku 7 pedoman asesmen lapangan s2Muhamad Fauzi
 

Mais de Muhamad Fauzi (6)

Kurikulum smk farmasi
Kurikulum smk farmasiKurikulum smk farmasi
Kurikulum smk farmasi
 
Bab ii profil dan pengembangan renop 2013 2014
Bab ii profil dan pengembangan renop 2013 2014Bab ii profil dan pengembangan renop 2013 2014
Bab ii profil dan pengembangan renop 2013 2014
 
Hasil ipm 2010
Hasil ipm 2010Hasil ipm 2010
Hasil ipm 2010
 
Formulir5 stikes analis_kesehatan_diii
Formulir5 stikes analis_kesehatan_diiiFormulir5 stikes analis_kesehatan_diii
Formulir5 stikes analis_kesehatan_diii
 
Buku 7 pedoman asesmen lapangan s2
Buku 7 pedoman asesmen lapangan s2Buku 7 pedoman asesmen lapangan s2
Buku 7 pedoman asesmen lapangan s2
 
Pedoman ta skripsi
Pedoman ta skripsiPedoman ta skripsi
Pedoman ta skripsi
 

Último

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 

Último (20)

Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 

L hammonds adventure

  • 1. Posts: 138 LHammonds Special Member My Notes for Installing Zimbra OSE on Ubuntu Server 10.04 LTS Greetings and salutations, I hope this thread will be helpful to those who follow in my foot steps as well as getting any advice based on what I have done / documented. I am a documentation freak so this will probably grow into a very LARGE step-by-step process. If useful, it will probably be best to convert to a wiki once completed. This is a Work-In-Progress topic so I will be updating this thread as I go through this transition from MS Exchange to Zimbra. High-level overview This thread will cover installation of Ubuntu server inside a virtual machine vSphere 4.1 running on ESXi 4.1 servers. Although there is some VMware-specific steps, they are very few and the majority of this documentation will work for other VMs such as VirtualBox or even directly installed onto a physical machine. It will also cover the installation and configuration of Zimbra OSE and the Zimbra desktop client. This is a merge of several other guides, comments and my own experience of putting it all together in one place in a format that is easy for me to follow and reproduce the same results (yes, I create documentation that I will have to re-read one day because of my bad memory problems!). Please excuse my ignorance since I am fairly new to Linux and Zimbra...if you have any advice on doing things better, please let me know. I love feedback and learning better ways of doing things! Company background and environment I have finished evaluating different mail options for my company and we decided to make the switch to Zimbra. We are a small shop of about 200 employees and are currently using Microsoft Exchange 2003 on a physical server. We are going to switch from Exchange to Zimbra. We are not fully utilizing Exchange features and are mainly using it for email, contacts, calendars and shared calendars (for scheduling meeting rooms). We use Active Directory (Windows 2003 domain) to manage users and distribution lists. The desktops are mainly Windows XP and some newer boxes are coming in with Windows 7. We are using Microsoft Outlook with personal folders since we have mailbox size restrictions of 200 MB per mailbox as well as the web interface for people that constantly move from desk-to-desk. iPhones and iPads are also being used as portable devices. The email server will be sitting behind a firewall on our LAN. Here is a graphic representation of the network layout:
  • 2. About the IT staff We are primarily a Microsoft shop and as such, most of us (3) have Microsoft certifications such as MCSE, MCDBA and MCP. None of us are Unix administrators but we are fairly competent in the use of the system from having to support an AIX server so we are comfortable in the VI editor but know very little in terms of Unix hardware and software administration (just basic user stuff, enough to be dangerous) The deployment process
  • 3. Here are the high-level milestones for this project. Phase 1 - Setup a fully-functional system for testing, training and migration. Phase 2 - Create Backup / Restore process and documentation Phase 3 - Install client software on all devices Phase 4 - Create and deploy training materials (web docs / videos) Phase 5 - Migrate users (over a weekend) Phase 6 - Decommission old system (with a flamethrower) Tools utilized in this process Ubuntu Server 10.04 LTS, 64-bit Zimbra OSE 7.2.0, 64-bit Zimbra Desktop Client 7.1.4 Portable PuTTY 0.62 VMware vSphere 4.1.0 Helpful links The list below are sources of information that helped me configure this system as well as some places that might be helpful to me later on as this process continues. Ubuntu Documentation Zimbra Network Edition Documentation (PDF files) Zimbra Open Source Edition Documentation (PDF files) Zimbra Desktop User Guide Ubuntu Firewall Basics Firewall Configuration for Zimbra Ubuntu AppArmor Basics Ubuntu 8 and Zimbra Install Guide Making Zimbra and BIND Work Together Split DNS Guide Z-Push (Over-The-Air ActiveSync) Funambol (Over-The-Air iPhone contact sync) djigzo (email encryption @ the gateway) Mondo Rescue (Ubuntu OS backup) MailArchiva (email Journaling and archival) TurnKeyLinux Zimbra Appliance (fast-n-easy to get running even if you are 100% unfamiliar with Linux/Zimbra) ZeXtras Migration Tool (upgrade OS or change from dedicated to multi-domain server) Location of Zimbra Log Files Zimbra Online Quote Tool
  • 4. Assumptions This documentation will need to make use of some very-specific information that will most-likely be different for each person / location. And as such, I will note some of these in this section. They will be highlighted in red throughout the document as a reminder that you should plug-in your own value rather than actually using my "place-holder" value. Under no circumstance should you use that actual values I list below. They are placeholders for the real thing. This is just a checklist template you need to have answered before you start the install process. Wherever you see RED in this document, you need to substitute it for what your company uses. Use the list below as a template you need to have answered before you continue. Ubuntu Server name: mail Internet domain: mydomain.com Server domain alias (Windows): work Server fully-qualified windows domain: work.mydomain.com Ubuntu Server IP address: 192.168.107.25 (my attempt at geek humor...raise your hand if you get it) Ubuntu Server IP subnet mask: 255.255.255.0 Ubuntu Server IP gateway: 192.168.107.1 Internal DNS Server 1: 192.168.107.23 Internal DNS Server 2: 192.168.107.212 Internal Active Directory: 192.168.107.212 External ISP DNS Server 1: 200.100.10.1 External ISP DNS Server 2: 200.100.10.2 External IP to Domain: 198.100.100.100 Ubuntu Admin ID: administrator Ubuntu Admin Password: myadminpass Ubuntu Root Password: myrootpass Zimbra Admin Password: myzimbrapass I also assume the reader knows how to use the VI editor. If not, you will need to beef up your skill set or use a different editor in place of it. __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) Last edited by LHammonds; 05-07-2012 at 03:03 PM.. #2 (permalink) 04-26-2012, 07:07 PM LHammonds Special Member Posts: 138
  • 5. Analysis and Design Analysis and Design The user base will probably not exceed 300 any time soon based on the company size over the last 80 years. A single server design is chosen for this deployement based on the amount of current users (~200) The Ubuntu Server Long-Term Support (LTS) is free but we have the option of buy support and that is the main reason this server was selected. Zimbra OSE is also free but we have the option of buying support by upgrading to the Network Edition. The Ubuntu LTS / Zimbra OSE combination makes for an excellent choice to evaluate the products (without incurring licensing fees) as well as having an upgrade path to obtain support. Much of how the system will run is based on how you install / configure Ubuntu before you ever install Zimbra. The largest decision over the configuration of Ubuntu seems to be how the hard drive space is sliced up (partitioned). I lot of my time was spent researching and learning the various options when it comes to the design layout of the storage. The Zimbra documentation's recommendation for Ubuntu in this area basically says to put everything on one LVM/Volume. I can see how tech support would want to favor a setup like this because it makes it easier to troubleshoot. However, I would rather make use of a design that allows for dynamic growth and fine-tuning if need be. I also do not like being caught offguard with a scenario where space is filled up with no immediate option other than deleting files. Long-term life and growth of the system as well as budgeting concerns have to be taken into consideration. Based on my observations during the first Zimbra install, I decided that a single volume wasn't a good idea, especially having continual-growth of a folder that is on the root volume. I would rather contain the root volume to mainly just static data that won't grow much and push the other folders that are dynamic into their own volumes. In case you don't know, filling up the root volume on a *nix system is a very bad thing and should be avoided at all costs. I also want to configure it where the file systems are not taking up 100% of the logical volume. This will allow me (through automated scripts) to grow the file system as needed and give me some time to add more drives if necessary or shrink other volumes to get more space. Here are my thoughts on how to slice up the space. Boot - This will remain static in size. It is also the only space residing outside the Logical Volume Manager (LVM)
  • 6. Root volume - Operating system and everything else which should remain fairly static. Swap volume - This will remain static in size. However, if amount of RAM is adjusted, this should be adjusted as well. Opt volume - This Zimbra storage will continue to grow over time. Backup volume - This will contain a local backup of the Opt volume and individually compressed mailbox archives. So space needs to be around double /opt/zimbra. Temp volume - This location will be used to hold data during backups, archives and restores and should be about double the size of opt/zimbra. Offsite Storage - This will be handled elsewhere but will be mounted on this server. My estimated mailbox store will be about 25 GB. However, we will start this server off with a much lower number. We will then pretend some event happened such as acquiring an additional company / employees. This will increase our storage needs and we will go through adjusting the entire system to accommodate a larger storage capacity. This will be a good exercise / documentation for what will eventually need to be done later to handle growth. To get a good idea of the hard drive layout and to understand the process better, here is a graphical representation of the initial design for the server:
  • 7. These numbers will be used for the initial build of the system: boot = 200 MB root = 4 GB swap = 8 GB opt = 10 GB temp = 20 GB
  • 8. backup = 20 GB Virtual Machine Settings Virtual Manager: VMware vSphere Client 4.1 Virtual Host: VMware ESXi Server 4.1 Configuration: Custom Name: ZimbraMail Datastore: MainOffice-LUN0 Virtual Machine Version: 7 Guest Operating System: Linux, Version: Ubuntu Linux (64-bit) Number of virtual processors: 1 Memory Size: 2048 MB Number of NICs: 1 NIC 1: VM Network Adapter: E1000, Connect at Power On: Checked SCSI controller: LSI Logic Parallel Select a Disk: Create a new virtual disk Create a Disk: 63 GB, No thin provisioning, No cluster features, Store with the virtual machine Advanced Options: Virtual Device Node = SCSI (0:0) Remove Floppy Drive Mount CD/DVD Drive to Ubuntu ISO (ubuntu-10.04.4-server-amd64.iso). Make sure CD/DVD is set to Connect at power on Set boot options to Force BIOS Setup so you can set CDROM to boot before the Hard Disk Install PuTTY The 1st time I installed Ubuntu and Zimbra, I used the console for everything but it was painfully slow to view man (manual) pages and navigating in VI (text editor). However, I found out that PuTTY is a far better solution for your Ubuntu console because it handles the screen draws much faster and allows for scrolling and copying text. Download the portable edition and run the install...except it doesn't really "install" like a normal program, it simply extracts to a specified folder and will run from that folder even if you put it on a USB stick and carry over to a new computer (requires no install to run and thus leaves a very small footprint on your system) 1. Start PuTTY 2. Type the following and click the Save button: Host Name: mail (or the IP such as 192.168.107.25) Port: 22 Connection type: SSH Saved Sessions: zimbra 3. Now all you have to do is double-click on the zimbra session and it will connect to
  • 9. your server (when online). __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) #3 (permalink) 04-26-2012, 07:14 PM LHammonds Special Member Posts: 138 Install Ubuntu Server Install Ubuntu Server NOTE: During the setup process, we are going to use the root account to make things easier. Later on, it will be best to use the "sudo" command to only temporarily grant root access rather than logging in with root access. 1. Power on the Virtual Machine (VM) 2. Press {ENTER} to accept English 3. Select Install Ubuntu Server {ENTER} 4. Press {ENTER} to accept English 5. Press {ENTER} to accept United States 6. Select No to not detect keyboard layout 7. Press {ENTER} to accept USA 8. Press {ENTER} to accept USA 9. Type mail {ENTER} (this is your hostname) 10. Press {ENTER} to accept detected time zone (America/Chicago) 11. Select Manual {ENTER} 12. Select SCSI3 (0,0,0) (sda) - 67.6 GB VMware Virtual disk {ENTER} 13. Select Yes to create new empty partition table, {ENTER} 14. Select pri/log 67.6 GB FREE SPACE {ENTER} 15. Select Create a new partition {ENTER} 16. Type 200 MB, {ENTER} (NOTE: This will be the /boot partition) 17. Select Primary {ENTER} 18. Select Beginning {ENTER} 19. Select Use as: Ext4 journaling file system {ENTER} 20. Select Ext2 file system {ENTER} 21. Select Mount point: / {ENTER} 22. Select /boot - static files of the boot loader {ENTER} 23. Select Bootable flag: off {ENTER} (NOTE: This toggles it on) 24. Select Done setting up the partition {ENTER} 25. Select Configure the Logical Volume Manager {ENTER} 26. Select Yes to write change to disks and configure LVM, {ENTER} 27. Select Create volume group {ENTER} 28. Type LVG {ENTER}
  • 10. 29. Select /dev/sda free #1 (67445; FREE SPACE), {SPACEBAR}, {ENTER} 30. Select Yes to write change to disks and configure LVM, {ENTER} 31. Select Create logical volume {ENTER} 32. Select LVG (67440MB) {ENTER} 33. Type swap {ENTER} 34. Type 8G {ENTER} (NOTE: This is double the amount of RAM) 35. Select Create logical volume {ENTER} 36. Select LVG (59441MB) {ENTER} 37. Type bak {ENTER} 38. Type 20G {ENTER} 39. Select Create logical volume {ENTER} 40. Select LVG (39443MB) {ENTER} 41. Type opt {ENTER} 42. Type 10G {ENTER} 43. Select Create logical volume {ENTER} 44. Select LVG (29444MB) {ENTER} 45. Type temp {ENTER} 46. Type 20G {ENTER} 47. Select Create logical volume {ENTER} 48. Select LVG (9445MB) {ENTER} 49. Type root {ENTER} 50. Type 9445MB {ENTER} (we are letting it take what is left over) 51. Select Finish {ENTER} 52. Select #1 8.0 GB directly under LVM VG LVG, LV swap, {ENTER} 53. Select Use as: do not use {ENTER} 54. Select swap area {ENTER} 55. Select Done setting up the partition {ENTER} 56. Select #1 9.4 GB directly under LVM VG LVG, LV root, {ENTER} 57. Select Use as: do not use {ENTER} 58. Select Ext4 journaling file system {ENTER} 59. Select Mount point: none {ENTER} 60. Select / - the root file system {ENTER} 61. Select Done setting up the partition {ENTER} 62. Select #1 20.0 GB directly under LVM VG LVG, LV bak, {ENTER} 63. Select Use as: do not use {ENTER} 64. Select Ext4 journaling file system {ENTER} 65. Select Mount point: none {ENTER} 66. Select Enter manually {ENTER} 67. Type /var/backup {ENTER} 68. Select Label: none {ENTER} 69. Type backup {ENTER} 70. Select Done setting up the partition {ENTER} 71. Select #1 10.0 GB directly under LVM VG LVG, LV opt, {ENTER} 72. Select Use as: do not use {ENTER} 73. Select Ext4 journaling file system {ENTER} 74. Select Mount point: none {ENTER} 75. Select /opt - add-on application software packages {ENTER} 76. Select Label: none {ENTER} 77. Type zimbra {ENTER}
  • 11. 78. Select Done setting up the partition {ENTER} 79. Select #1 20.0 GB directly under LVM VG LVG, LV temp, {ENTER} 80. Select Use as: do not use {ENTER} 81. Select Ext4 journaling file system {ENTER} 82. Select Mount point: none {ENTER} 83. Select Enter manually {ENTER} 84. Type /var/temp {ENTER} 85. Select Label: temp {ENTER} 86. Select Done setting up the partition {ENTER} 87. Here is what the screen looks like at this point: Partitions 88. Select Finish partitioning and write changes to disk {ENTER} 89. Select Yes to write changes to disk, {ENTER} 90. Type Administrator, {ENTER} for the full name (NOTE: Do not use "zimbra" as a choice here) 91. Press {ENTER} to accept the default of the lowercase name of administrator 92. Type myadminpass, {ENTER}, myadminpass, {ENTER} 93. Select No, {ENTER} to not encrypt your home directory 94. Press {ENTER} to accept a blank line for the HTTP proxy 95. Select Install security updates automatically, {ENTER} 96. Highlight only OpenSSH server and press {SPACEBAR} to enable, {ENTER} to continue. NOTE: This allows us to use PuTTY after installation to connect to the server. 97. Select Yes, {ENTER} to install GRUB boot loader to the master boot record 98. Installation Complete - from the VM menu, select VM --> Edit Settings and select CD/DVD Drive 1 and change to "Client Device" which will effectively remove the ISO. Now press {ENTER} to reboot. Initial Configurations 1. At the console login prompt, login with your administrator account (administrator / myadminpass) 2. At the $ prompt, type sudo passwd root {ENTER}, type your administrator password (myadminpass), it will ask for a new password, type myrootpass and verify. NOTE: This enables the root account. 3. At the $ prompt, change to the super user root account by typing su {ENTER} and then provide the new root password you just configured. 4. Type vi /etc/network/interfaces {ENTER} and change the following: (We need to change the network interface card (NIC) from using DHCP to a static IP) From: Code: iface eth0 inet dhcp To:
  • 12. Code: iface eth0 inet static address 192.168.107.25 netmask 255.255.255.0 gateway 192.168.107.1 network 192.168.107.0 broadcast 192.168.107.255 NOTE #1: You may need to manually remove the DHCP record (lease) associated to this Ubuntu server from your DHCP server so the correct IP can be found by other machines on the network. This can be avoided by temporarily configuring the VM Network Adapter connection to be "Host Only Network" instead of "VM Network" so the server is isolated during setup...at least until you reach the testing of the static IP below. NOTE #2: You might also need to manually add a HOST(A) record to your Windows DNS server (for mail.mydomain.com and mail.work.mydomain.com) 5. Restart the network by typing /etc/init.d/networking restart 6. Sanity check! Type ifconfig and make sure the settings are correct. Then type ping Google or similar and see if ping works. 7. Shutdown and power off the server by typing shutdown -P now {ENTER} 8. At this point forward, you can use PuTTY to access the console rather than the console itself for better performance, ability to scroll, etc. 9. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 1 and description of Ubuntu Server 10.04.4 LTS, clean install, Static IP: 192.168.107.25 and click OK __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) #4 (permalink) 04-26-2012, 07:22 PM LHammonds Special Member Posts: 138 Volume / Disk Management Volume / Disk Management At this point, let's assume something has changed and we need additional storage (e.g. acquired new company, added more people, etc.) For this scenario, we are expecting storage space to require 25 GB for all user mailboxes. If
  • 13. they need 25 GB for storage, let's double that amount for the actual size. Here is the planned adjustments for each file system: opt = 50 GB (double the expected/actual mailbox storage) temp = 100 GB (double the opt size) backup = 100 GB (double the opt size) In the analysis and design section, we wanted to have some file systems smaller than the logical volume on which they sit. This will allow us to allocate additional space when needed. However, when we created the volumes, Ubuntu automatically expanded the file systems to the maximum size of the volume. Normally, this is OK...but we want a system that will allow growth when needed and ensure that we will have time to add additional hard drives BEFORE they are needed which will keep us from being stuck between a rock and a hard place! The design calls for the backup, opt and temp file systems to be slightly smaller than the maximum space available for the logical volume. So, let's make the logical volumes an extra 25 GB larger. This means that we will need an additional 275 GB of storage {(75 + 125 + 125 ) - 50}. If we add two drives that are 140 GB each, that will be just enough to cover our needs. (NOTE: This was an arbitrary number because I wanted to show you how to add 2 drives to the system) If we were to type df -h right now, we should see something like this: Code: Filesystem /dev/mapper/LVG-root none none none none none /dev/mapper/LVG-bak /dev/mapper/LVG-opt /dev/mapper/LVG-temp /dev/sda1 Size 8.7G 1000M 1005M 1005M 1005M 1005M 19G 9.2G 19G 179M Used 824M 184K 0 32K 0 0 172M 149M 172M 17M Avail Use% Mounted on 7.5G 10% / 1000M 1% /dev 1005M 0% /dev/shm 1005M 1% /var/run 1005M 0% /var/lock 1005M 0% /lib/init/rw 18G 1% /var/backup 8.6G 2% /opt 18G 1% /var/temp 152M 10% /boot Since I am running VMware, adding additional space is a snap. However, I will add it in such a way that Ubuntu will see 2 drives added to the system just as if we were to add 2 physical drives to the server. 1. Shutdown and power off the server by typing shutdown -P now {ENTER} 2. In the vSphere client, right-click the Virtual Machine and choose Edit Settings. 3. On the hardware tab, click the Add button and select Hard Disk. Click Next, choose
  • 14. "Create a new virtual disk", click Next, set the size to 140 GB, click Next, Next, Finish. 4. Add another 140 GB disk using the same steps above and click OK to close the settings and allow VMware to process the changes. Collect information about the newly added drives. 1. Start the Ubuntu server and connect using PuTTY. 2. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) 3. Type pvdisplay which should show something similar to this: Code: PV Name VG Name PV Size Allocatable PE Size Total PE Free PE Allocated PE PV UUID /dev/sda5 LVG 62.81 GiB / not usable 3.00 MiB yes (but full) 4.00 MiB 16079 0 16079 XjUHyI-kloS-kicz-jLdd-E01t-7RYP-K3YqvM The important bits of info here are the PV Name and VG Name for our existing configuration. 4. Type fdisk -l which should show something similar to this (however I abbreviated it to show just the important parts): Code: Disk /dev/sda: 67.6 GB, 67645734912 bytes Device Boot Start End Blocks Id /dev/sda1 * 1 25 194560 83 Partition 1 does not end on cylinder boundary. /dev/sda2 25 8224 65862657 5 /dev/sda5 25 8224 65862656 8e Disk /dev/sdb: 150.3 GB, 150323855360 bytes Disk /dev/sdb doesn't contain a valid partition table Disk /dev/sdc: 150.3 GB, 150323855360 bytes Disk /dev/sdc doesn't contain a valid partition table System Linux Extended Linux LVM The important bits of info here are the device paths for the new drives which are
  • 15. highlighted in red. Prepare the first drive (/dev/sdb) to be used by the LVM Type the following: Code: fdisk /dev/sdb n (Create New Partition) p (Primary Partition) 1 (Partition Number) {ENTER} (use default for first cylinder) {ENTER} (use default for last cylinder) t (Change partition type) 8e (Set to Linux LVM) p (Preview how the drive will look) w (Write changes) Prepare the second drive (/dev/sdc) to be used by the LVM Do the exact same steps as above but start with fdisk /dev/sdc Create physical volumes using the new drives If we type fdisk -l, we now see /dev/sdb1 and /dev/sdc1 which are Linux LVM partitions. Type the following to create physical volumes: Code: pvcreate /dev/sdb1 pvcreate /dev/sdc1 Now add the physical volumes to the volume group (LVG) by typing the following: Code: vgextend LVG /dev/sdb1 vgextend LVG /dev/sdc1 Now that the space of both drives have been added to the logical volume group called LVG, we can now allocate that space to grow the logical volume. To get a list of volume paths to use in the next commands, type lvscan to show your current volumes and their sizes. Type the following to grow each volume by a specified amount (the number after the plus sign):
  • 16. Code: lvextend -L+65G /dev/LVG/opt lvextend -L+105G /dev/LVG/bak lvextend -L+105G /dev/LVG/temp or you can specify the exact size by excluding the plus sign and specifying the end-result size you want: Code: lvextend -L75G /dev/LVG/opt lvextend -L125G /dev/LVG/bak lvextend -L125G /dev/LVG/temp To see the new sizes, type lvscan The last thing to do now is the actual growth of the file systems. We want to grow the existing file systems but only to a certain amount so we do not take up all the space in the volume...we want room to grow in the future so we have time to order and install new drives when needed. Code: resize2fs /dev/LVG/opt 50G resize2fs /dev/LVG/bak 100G resize2fs /dev/LVG/temp 100G If we need to increase space in /opt at a later point, we can issue the following command (without any downtime): Code: resize2fs /dev/LVG/opt 51G We could continue to increase this particular file system all the way until we reach the limit of the volume which is 75 GB at the moment. Remember, df -h will tell you the size of the file system and lvscan will tell you the size of the volumes where the file systems live in. If we were to type df -h right now, we should see something like this: Code: Filesystem /dev/mapper/LVG-root none none none none Size 8.7G 1000M 1005M 1005M 1005M Used 824M 200K 0 32K 0 Avail Use% Mounted on 7.5G 10% / 1000M 1% /dev 1005M 0% /dev/shm 1005M 1% /var/run 1005M 0% /var/lock
  • 17. none 1005M /dev/mapper/LVG-bak 99G /dev/mapper/LVG-opt 50G /dev/mapper/LVG-temp 99G /dev/sda1 179M 0 1005M 188M 94G 159M 47G 188M 94G 17M 152M 0% 1% 1% 1% 10% /lib/init/rw /var/backup /opt /var/temp /boot EDIT (2012-05-03): In favor of manage by exception, I wrote a script that can be scheduled to run daily to check the file systems to see if they are getting close to filling up and will automatically expand them a little bit and give you an email notice. Everything is done on the gigabyte level. If you do not want the script to perform the increase, simply add a pound sign in front of the resize2fs command on line 64 to comment it out. Might also want to modify the log and email messages so it does not look like it actually "performed" the resize but instead is telling YOU how to perform the resize. Here are the lines I added to my crontab schedule which will check each file system I expect will grow on a daily basis @ 1am, 2am and 3am. I have them checking to see if we have less than 5GB available and if so, it will try to increase by 1GB: Code: 0 1 * * * /var/scripts/prod/check-storage.sh opt 5 1 > /dev/null 2>&1 0 2 * * * /var/scripts/prod/check-storage.sh bak 5 1 > /dev/null 2>&1 0 3 * * * /var/scripts/prod/check-storage.sh temp 5 1 > /dev/null 2>&1 /var/scripts/prod/check-storage.sh Code: #!/bin/bash ############################################# ## Name : check-storage.sh ## Version : 1.2 ## Date : 2012-05-01 ## Author : LHammonds ## Purpose : Check available space for a file system and expand if necessary. ## Compatibility : Verified on Ubuntu Server 10.04.4 LTS ## Requirements : None ## Run Frequency : Recommend once per day for each FS to monitor. ## Parameters : ## 1 = (Required) File System name (e.g. opt) ## 2 = (Required) File System Threshold (e.g. 2G) ## 3 = (Required) Amount to increase File System (e.g. 1G) ## Exit Codes : ## 0 = Success (either nothing was done or FS expanded without error) ## 1 = ERROR: Missing or incorrect parameter(s) ## 2 = ERROR: Invalid parameter value(s) ## 4 = ERROR: Lock file detected ## 8 = ERROR: Resize2fs error ## 16 = SEVERE: No room to expand ## 32 = ERROR: Script not run by root user ################ CHANGE LOG #################
  • 18. ## DATE WHO WHAT WAS CHANGED ## ---------- --- ---------------------------## 2012-05-01 LTH Created script. ## 2012-05-02 LTH Improved log messages. ## 2012-05-02 LTH Improved email messages. ############################################# ## Import standard variables and functions. ## source /var/scripts/common/standard.conf ## Define local variables. LOGFILE="${TEMPDIR}/check-storage.log" LOCKFILE="${TEMPDIR}/check-storage.lock" ErrorFlag=0 ReturnCode=0 ####################################### ## FUNCTIONS ## ####################################### function f_cleanup() { if [ -f ${LOCKFILE} ];then ## Remove lock file so other check space jobs can run. rm ${LOCKFILE} 1>/dev/null 2>&1 fi exit ${ErrorFlag} } function f_showhelp() { echo -e "nUsage : ${SCRIPTNAME} FileSystemName ThresholdSizeInGB AmountToIncreaseByInGBn" echo -e "nExample: ${SCRIPTNAME} opt 2 1n" } function f_auto-increment() { let RoomInLV=${LVSize}-${FSSize} if [[ ${RoomInLV} -gt ${FSIncreaseBy} ]]; then ## There is room in the LV to increase space to the FS. resize2fs ${FSVol} ${NewFSSize}G ReturnCode=$? echo "`date +%Y-%m-%d_%H:%M:%S` --- resize2fs ${FSVol} ${NewFSSize}G, ReturnCode=${ReturnCode}" | tee -a ${LOGFILE} if [[ ${ReturnCode} -ne 0 ]]; then ## There was an error in resize2fs. return ${ReturnCode} fi else ## There is not enough room in the LV to increase space in the FS. return 50
  • 19. fi return 0 } ####################################### ## MAIN PROGRAM ## ####################################### if [ -f ${LOCKFILE} ]; then # Lock file detected. Abort script. echo "Check space script aborted" echo "This script tried to run but detected the lock file: ${LOCKFILE}" echo "Please check to make sure the file does not remain when check space is not actually running." f_sendmail "ERROR: check storage script aborted" "This script tried to run but detected the lock file: ${LOCKFILE}nnPlease check to make sure the file does not remain when check space is not actually running.nnIf you find that the script is not running/hung, you can remove it by typing 'rm ${LOCKFILE}'" ErrorFlag=4 f_cleanup else echo "`date +%Y-%m-%d_%H:%M:%S` ${SCRIPTNAME}" > ${LOCKFILE} fi ## Requirement Check: Script must run as root user. if [ "$(id -u)" != "0" ]; then ## FATAL ERROR DETECTED: Document problem and terminate script. echo "ERROR: Root user required to run this script." echo "" ErrorFlag=32 f_cleanup fi ## Check existance of required command-line parameters. case "$1" in "") f_showhelp ErrorFlag=1 f_cleanup ;; --help|-h|-?) f_showhelp ErrorFlag=1 f_cleanup ;; *) FSName=$1 ;; esac case "$2" in "")
  • 20. f_showhelp ErrorFlag=1 f_cleanup ;; --help|-h|-?) f_showhelp ErrorFlag=1 f_cleanup ;; *) FSThreshold=$2 ;; esac case "$3" in "") f_showhelp ErrorFlag=1 f_cleanup ;; --help|-h|-?) f_showhelp ErrorFlag=1 f_cleanup ;; *) FSIncreaseBy=$3 ;; esac ## Check validity of File System name. case "${FSName}" in "opt") FSVol="/dev/LVG/opt" FSMap="/dev/mapper/LVG-opt" ;; "bak") FSVol="/dev/LVG/bak" FSMap="/dev/mapper/LVG-bak" ;; "temp") FSVol="/dev/LVG/temp" FSMap="/dev/mapper/LVG-temp" ;; *) echo "ERROR: ${FSName} does not match a known file system defined in this script." f_showhelp ErrorFlag=2 f_cleanup ;; esac
  • 21. ## Check validity of threshold value. test ${FSThreshold} -eq 0 1>/dev/null 2>&1 if [[ $? -eq 2 ]]; then ## Threshold parameter is not an integer. echo "ERROR: ${FSThreshold} is not an integer." f_showhelp ErrorFlag=2 f_cleanup fi ## Check validity of increment value. test ${FSIncreaseBy} -eq 0 1>/dev/null 2>&1 if [[ $? -eq 2 ]]; then ## FSIncreaseBy parameter is not an integer. echo "ERROR: ${FSIncreaseBy} is not an integer." f_showhelp ErrorFlag=2 f_cleanup fi ## Get available space for the file system. FSAvailable="`df --block-size=g ${FSMap} | awk '{ print $4 }' | tail -n 1 | sed 's/G//'`" ## Get the current size of the File System. FSSize="`df --block-size=g ${FSMap} | awk '{ print $2 }' | tail -n 1 | sed 's/G//'`" ## Get the current size of the Logical Volume for the File System LVSize="`lvs --noheadings --nosuffix --units=g ${FSMap} | awk '{ print $4}' | sed 's/[.].*//'`" ## Calculate the new size of the FS in case we need it. let NewFSSize=${FSSize}+${FSIncreaseBy} if [[ ${FSAvailable} -lt ${FSThreshold} ]]; then echo "`date +%Y-%m-%d_%H:%M:%S` - Starting expansion of ${FSVol}" | tee a ${LOGFILE} echo "`date +%Y-%m-%d_%H:%M:%S` --- LVSize=${LVSize}GB, FSSize=${FSSize}GB, FSAvail=${FSAvailable}GB, FSThreshold=${FSThreshold}GB, FSIncreaseBy=${FSIncreaseBy}GB" | tee -a ${LOGFILE} ## Run the auto-expansion function. f_auto-increment ReturnCode=$? case ${ReturnCode} in 0) f_sendmail "NOTICE: File System Expanded" "${FSVol} was expanded because it was nearing max capacity. Please review disk space usage and plan appropriately. LVSize=${LVSize}GB, FSSize=${FSSize}GB, FSAvailable=${FSAvailable}GB, FSThreshold=${FSThreshold}GB, FSIncreaseBy=${FSIncreaseBy}GB" ;;
  • 22. 50) echo "`date +%Y-%m-%d_%H:%M:%S` - SEVERE: No room to expand ${FSVol}" | tee -a ${LOGFILE} ErrorFlag=16 f_sendmail "SEVERE: No room to expand ${FSVol}" "There is not enough room in the Logical Volume to expand the ${FSVol} File System. Immediate action is required. Make sure there is free space in the Volume Group 'LVG' and then expand the Logical Volume...then expand the File System.nnLVSize=${LVSize}GB, FSSize=${FSSize}GB, FSAvailable=${FSAvailable}GB, FSThreshold=${FSThreshold}GB, FSIncreaseBy=${FSIncreaseBy}GB.nnType 'vgs' to see if there is any free space in the Volume Group which can be given to the Logical Volume.nnType 'lvs' to see the current sizes of the LVs.nnType 'lvdisplay' to see a list of Logical Volumes so you can get the LV Name which is used in the lvextend and resize2fs commands.nnType 'lvextend -L+1G /dev/LVG/opt' if you want to extend the opt Logical Volume by 1 gigabyte (assuming there is 1GB available in the Volume Group).nnType 'df --block-size=g' to see a list of file systems and their associated size and available space.nnType 'resize2fs /dev/LVG/opt ${NewFSSize}G' to set the size of opt to ${NewFSSize} gigabytes. Make sure you set the size to the desired endresult which should be LARGER than the current FS size so you do not lose data." ;; *) echo "`date +%Y-%m-%d_%H:%M:%S` - ERROR: Expansion failure for ${FSVol}" | tee -a ${LOGFILE} ErrorFlag=8 f_sendmail "ERROR: File System Expansion Failed" "${FSVol} Expansion failed with return code of ${ReturnCode}. LVSize=${LVSize}GB, FSSize=${FSSize}GB, FSAvailable=${FSAvailable}GB, FSThreshold=${FSThreshold}GB, FSIncreaseBy=${FSIncreaseBy}GB" ;; esac echo "`date +%Y-%m-%d_%H:%M:%S` - Finished expansion of ${FSVol}" | tee a ${LOGFILE} else echo "`date +%Y-%m-%d_%H:%M:%S` - ${FSVol} ${FSAvailable}G>${FSThreshold}G No action required." | tee -a ${LOGFILE} fi ## Perform cleanup routine. f_cleanup Here is the typical output when it does not have to increase the FS: /var/temp/check-storage.log Code: 2012-05-01_01:00:00 2012-05-01_02:00:00 2012-05-01_03:00:00 2012-05-02_01:00:00 - /dev/LVG/opt 44G>5G No action required. /dev/LVG/bak 91G>5G No action required. /dev/LVG/temp 93G>5G No action required. /dev/LVG/opt 44G>5G No action required.
  • 23. 2012-05-02_02:00:00 2012-05-02_03:00:00 2012-05-03_01:00:00 2012-05-03_02:00:00 2012-05-03_03:00:00 - /dev/LVG/bak 91G>5G No action required. /dev/LVG/temp 93G>5G No action required. /dev/LVG/opt 44G>5G No action required. /dev/LVG/bak 91G>5G No action required. /dev/LVG/temp 93G>5G No action required. Here is a sample of what the log will look like when it perform increases...notice how I had to increase the threshold in order for it to fire off the increase (but it still just issued a single gigabyte increase): /var/temp/check-storage.log Code: 2012-05-02_01:00:00 - Starting expansion of /dev/LVG/opt 2012-05-02_01:00:00 --- LVSize=75GB, FSSize=50GB, FSAvail=44GB, FSThreshold=55GB, IncreaseBy=1GB 2012-05-02_01:00:00 --- resize2fs /dev/LVG/opt 51, ReturnCode=0 2012-05-02_01:00:00 - Finished expansion of /dev/LVG/opt 2012-05-02_02:00:00 - Starting expansion of /dev/LVG/bak 2012-05-02_02:00:00 --- LVSize=125GB, FSSize=99GB, FSAvail=91GB, FSThreshold=100GB, IncreaseBy=1GB 2012-05-02_02:00:00 --- resize2fs /dev/LVG/bak 100, ReturnCode=0 2012-05-02_02:00:00 - Finished expansion of /dev/LVG/bak 2012-05-02_03:00:00 - Starting expansion of /dev/LVG/temp 2012-05-02_03:00:00 --- LVSize=125GB, FSSize=99GB, FSAvail=93GB, FSThreshold=100GB, IncreaseBy=1GB 2012-05-02_03:00:00 --- resize2fs /dev/LVG/temp 100, ReturnCode=0 2012-05-02_03:00:00 - Finished expansion of /dev/LVG/temp __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) Last edited by LHammonds; 05-03-2012 at 06:58 AM.. #5 (permalink) 04-26-2012, 07:26 PM LHammonds Special Member Software Configurations Software Configurations 1. Start the Ubuntu server and connect using PuTTY. 2. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) Posts: 138
  • 24. 3. At the $ prompt, type aptitude -y install vim-nox for use instead of the built-in VI editor. more info 4. At the $ prompt, type aptitude -y install bind9 to install a local DNS server. 5. At the $ prompt, type aptitude -y install p7zip-full to install 7-zip archive utility. 6. Type dpkg-reconfigure dash and answer No 7. Remove AppArmor to avoid problems by typing the following: Code: /etc/init.d/apparmor stop update-rc.d -f apparmor remove aptitude remove apparmor apparmor-utils 8. Reboot the server by typing reboot VMware Tools If you are installing under VMware like me, be sure to install the tools to insure maximum performance in a virtual environment. 1. In the VM toolbar for the VM, click Guest, Install VMware Tools 2. At the Ubuntu prompt, type the following: Code: mkdir /mnt/cdrom mount /dev/cdrom /mnt/cdrom ls /mnt/cdrom tar zxvf /mnt/cdrom/VMwareTools-x.x.x-xxxx.tar.gz -C /tmp/ (use the correct numbers version discovered from the list command in the prior step) cd /tmp/vmware-tools-distrib/ ./vmware-install.pl -d reboot Configure Ubuntu for File Sharing This file sharing section is optional but can be handy if you need to swap files between the Linux server and a Windows machine. This documentation will utilize this share for passing pre-configured files (configs, scripts, etc.) to make it faster/easier during installation. 1. Start the Ubuntu server and connect using PuTTY. 2. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass)
  • 25. 3. Install Samba by typing aptitude -y install samba smbfs (NOTE: To share a folder with Windows, you just need the samba package, to connect to a Windows share, you need both samba and smbfs) 4. Type the following commands: Code: cp /etc/samba/smb.conf /etc/samba/smb.conf.bak mkdir -p /srv/samba/share chown nobody:nogroup /srv/samba/share/ chmod 0777 /srv/samba/share 5. Edit the configuration file by typing vi /etc/samba/smb.conf 6. Change workgroup = WORKGROUP to workgroup = work (you are using the domain alias) 7. Change: Code: # security = user to: Code: security = user 8. Add the following section to the end of the file: Code: [share] comment = Ubuntu File Server Share path = /srv/samba/share browsable = yes guest ok = yes read only = no create mask = 0755 9. Save and exit the file. 10. Restart the samba services to utilize the new configuration by typing: Code: restart smbd restart nmbd
  • 26. 11. You should now be able to click Start --> Run and type mail or 192.168.107.25 {ENTER} and see an explorer window with a Share folder. Drag-n-drop a file into the Share folder. If it worked, it will not display an error message and you should be able to view it from the server by typing ls -l /srv/samba/share/ 12. Shutdown and power off the server by typing shutdown -P now {ENTER} 13. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 2 and description of Ubuntu Server 10.04.4 LTS, File share configured, Static IP: 192.168.107.25. The Snapshot Manager should now have a nice hierarchy of snapshots (STEP 1 --> STEP 2 --> You are here) Configure Windows Remote Mount Point The remote offsite location is a Windows 2008 server that has a vast amount of hard drive space and currently backs up other servers. Part of the backup process will be to write files to a mounted folder to a Windows share. First, let's document the variables for this solution below and highlight them in red throughout the document for easy identification. The values below are merely samples which you need to change in order to match your environment: Windows AD Domain Name: work Windows Server Name: SRV-Backup Windows Server IP: 192.168.107.218 Windows Share Name: zimbra Windows Physical Share Location: D:Zimbra Windows Share ID: zimbrashare Windows Share Password: zimbrapassword Create a share on a Windows 2008 server 1. In Windows Explorer, right-click on the D:Zimbra folder and select Properties 2. Click the Sharing tab 3. Click the Advanced Sharing button 4. Place a checkmark beside Share this folder 5. Change the Share name to zimbra 6. Set the Comment to Zimbra Backup 7. Click the Permissions button 8. Select Everyone and click the Remove button 9. Click the Add button 10. Type in your zimbra share account: workzimbrashare and click the Check Names button, click OK 11. Place a checkmark for Allow Full Control and click OK, click OK, click OK 12. Create a text file in the root of the shared folder called "online.txt" and you might want to add some text inside saying to never delete this file because it is used (will be)
  • 27. by a Zimbra backup script. Probably a good idea to make it read-only as well. Example: [B]D:zimbraonline.txt[B] Create an NFS mount to the Windows 2008 server Connecting to a Windows share requires the samba and smbfs packages to be installed. If you did not install them (from a prior section), type aptitude -y install samba smbfs 1. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) 2. Type the following commands: Code: mkdir -p /mnt/backup chown root:root /mnt/backup chmod 0755 /mnt/backup echo "This file is used to tell if the mount is active or not" > /mnt/backup/offline.txt chown root:root /mnt/backup/offline.txt chmod 0444 /mnt/backup/offline.txt touch /etc/cifspw chmod 0600 /etc/cifspw 3. Type vi /etc/cifspw and add the following text, save and exit the file: Code: username=workzimbrashare password=zimbrapassword 4. Type vi /etc/hosts and add the following line anywhere in the file: Code: 192.168.107.218 srv-backup 5. At this point, you might want to type ping srv-backup to make sure you typed the right IP address as well as seeing a good response. 6. To mount this system for backups, type the following command: Code: mount -t cifs //srv-backup/zimbra /mnt/backup --options
  • 28. nouser,rw,nofail,noatime,noexec,credentials=/etc/cifspw 7. To test it, type cp /etc/hosts /mnt/backup/hosts.txt and look on the Windows server and see if the file shows up. Then type rm /mnt/backup/hosts.txt and verify that the file was deleted on the windows server. 8. This would also be a good time to verify that you can see the "online.txt" file that will be used by the backup script. Type ls -l /mnt/backup/*.txt 9. To dismount the windows share, type the following command: Code: umount /mnt/backup The scripts will call a common mount and unmount function to connect to this share only when needed. However, if you would rather have it mounted all the time (even after a reboot), do the following (but remember to not use the mount/umount functions in the scripts later): 1. Type vi /etc/fstab and add the following line at the bottom of the file: Code: //srv-backup/zimbra /mnt/backup cifs nouser,rw,nofail,noatime,noexec,credentials=/etc/cifspw 0 2. Type mount -a and if it does not spew out any error messages, it will quietly mount the share. 3. To test it, type cp /etc/hosts /mnt/backup/hosts.txt and look on the Windows server and see if the file shows up. Then type rm /mnt/backup/hosts.txt and verify that the file was deleted on the windows server. 4. If you need to unmount it, simply type umount /mnt/backup and it will remain unmounted until you reboot. To make it permanent, you need to remove the line you added in the /etc/fstab file. Sometimes it is helpful during tests to toggle the mount on or off so here is a script you might find helpful. You can find the contents of "standard.conf" file further down the thread. togglemount.sh Code: #!/bin/bash ############################################# ## Name : togglemount.sh ## Version : 1.0 ## Date : 2011-11-05 ## Author : LHammonds 0
  • 29. ## Compatibility : Ubuntu Server 10.04.4 LTS ## Purpose : Toggle the mount status of a pre-configured backup mount. ## Run Frequency : Manual as needed. ## Exit Codes : ## 0 = success ## 1 = failure ################ CHANGE LOG ################# ## DATE WHO WHAT WAS CHANGED ## ---------- --- ---------------------------## 2011-11-05 LTH Created script. ############################################# ## Import common variables and functions. ## source /var/scripts/common/standard.conf ERRORFLAG=0 if [ -f ${OFFSITEDIR}/offline.txt ]; then echo "Windows share is not mounted. Mounting share now..." f_mount sleep 2 if [ -f ${OFFSITEDIR}/online.txt ]; then echo "Mount successful. Listing contents:" else echo "Mount failed. Listing contents:" ERRORFLAG=1 fi else echo "Windows share is mounted. Dismounting share now..." f_umount sleep 2 if [ -f ${OFFSITEDIR}/offline.txt ]; then echo "Dismount successful. Listing contents:" else echo "Dismount failed. Listing contents:" ERRORFLAG=1 fi fi ls -l ${OFFSITEDIR} exit ${ERRORFLAG} __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) #6 (permalink) 04-26-2012, 07:27 PM LHammonds Special Member Configure DNS Configure Domain Resolution (DNS) Posts: 138
  • 30. 1. Connect to the server using PuTTY 2. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) 3. Sanity check! Make sure BIND is running. Type /etc/init.d/bind9 status 4. At this point, you can save yourself a lot of typing if you have a copy of the configuration files on your PC and simply copy them to the share. Then you can set the appropriate file permissions and copy them where they need to go. But if not and this is your 1st time installing the server, here are the details for configuring by hand. 5. Edit the hosts by typing vi /etc/hosts and change the following: From: Code: 127.0.0.1 127.0.1.1 localhost mail.mydomain.com mail To: Code: 127.0.0.1 localhost.localdomain localhost 192.168.107.25 mail.mydomain.com mail 6. Edit the DNS servers by typing vi /etc/resolv.conf and set it to the following: Code: nameserver 127.0.0.1 nameserver 192.168.107.23 nameserver 192.168.107.212 nameserver 200.100.10.1 nameserver 200.100.10.2 domain mydomain.com search mydomain.com 7. Type the following commands: Code: mkdir /var/cache/bind/internal mkdir /var/cache/bind/external touch /var/cache/bind/internal/db.mydomain.com touch /var/cache/bind/internal/db.107.168.192.in-addr.arpa touch /var/cache/bind/external/db.mydomain.com cp /etc/bind/named.conf.options /etc/bind/named.conf.options.bak cp /etc/bind/named.conf.local /etc/bind/named.conf.local.bak cp /etc/bind/named.conf.default-zones /etc/bind/named.conf.default-zones.bak
  • 31. 8. Stop the DNS server by typing /etc/init.d/bind9 stop 9. Edit the DNS options by typing vi /etc/bind/named.conf.options and set the following: Code: options { directory "/var/cache/bind"; query-source address * port 53; forwarders { 200.100.10.1; 200.100.10.2; }; auth-nxdomain no; # conform to RFC1035 listen-on-v6 { any; }; }; NOTE: The IP addresses are public IP addresses of the DNS servers you use in the outside world. The query-source address line is to allow your machine to hit the DNS if oddball DNS ports are blocked. You can leave it commented if you do not need it. 10. Restart the network by typing /etc/init.d/networking restart 11. Type the following vi /etc/hostname and add the following text, save and exit: Code: mail.mydomain.com 12. To check results, type hostname and then hostname -f which should result with: Code: mail mail.mydomain.com 13. Edit the local DNS file by typing vi /etc/bind/named.conf.local and set the following: Code: acl internals { 127.0.0.0/8; 192.168.107.0/24; }; view "internal" { match-clients { internals; }; recursion yes; zone "mydomain.com" { type master; file "/var/cache/bind/internal/db.mydomain.com";
  • 32. }; zone "107.168.192.in-addr.arpa" { type master; file "/var/cache/bind/internal/db.107.168.192.inaddr.arpa"; }; }; view "external" { match-clients { any; }; recursion no; zone "mydomain.com" { type master; file "/var/cache/bind/external/db.mydomain.com"; }; }; 14. Edit the internal reverse zone file by typing vi /var/cache/bind/internal/db.107.168.192.in-addr.arpa and set the following: Code: $TTL 86400 @ IN 1 NS PTR SOA mail.mydomain.com. root.mydomain.com. ( 201109231448 ; Serial (increment after edit) 604800 ; Refresh 86400 ; Retry 2419200 ; Expire 86400) ; Negative Cache TTL mail.mydomain.com. mail.mydomain.com. 15. Edit the internal zone file by typing vi /var/cache/bind/internal/db.mydomain.com and set the following: Code: ; mydomain.com $TTL 86400 @ IN SOA root.mydomain.com. ( mail.mydomain.com. 201109231335 ; Serial 604800 86400 2419200 604800) ; ; ; ; (increment after edit) Refresh Retry Expire Negative Cache TTL ; Define the nameservers and the mail servers @ IN NS 192.168.107.25. IN MX 10 mail.mydomain.com. IN A 192.168.107.25 mail IN A 192.168.107.25 16. Edit the external zone file by typing vi /var/cache/bind/external/db.mydomain.com
  • 33. and set the following: Code: ; mydomain.com $TTL 86400 @ IN SOA root.mydomain.com. ( mail.mydomain.com. 201109231335 ; Serial 604800 86400 2419200 604800) ; ; ; ; (increment after edit) Refresh Retry Expire Negative Cache TTL ; Define the nameservers and the mail servers @ IN NS 198.100.100.100. IN MX 10 mail.mydomain.com. IN A 198.100.100.100 mail IN A 198.100.100.100 17. Since views were used, they also need to be used in the default zone. Type vi /etc/bind/named.conf.default-zones and set the following: Code: // prime the server with knowledge of the root servers acl internals-default { 127.0.0.0/8; 192.168.107.0/24; 192.168.106.0/24; here. }; // Keep adding all your internal subnets view "internal-default" { match-clients { internals-default; }; recursion yes; zone "." { type hint; file "/etc/bind/db.root"; }; // be authoritative for the localhost forward and reverse zones, and for // broadcast zones as per RFC 1912 zone "localhost" { type master; file "/etc/bind/db.local"; }; zone "127.in-addr.arpa" { type master; file "/etc/bind/db.127";
  • 34. }; zone "0.in-addr.arpa" { type master; file "/etc/bind/db.0"; }; zone "255.in-addr.arpa" { type master; file "/etc/bind/db.255"; }; }; 18. Ensure the correct ownership and permissions of all config files: Code: chown chown chmod chmod root:bind /var/cache/bind/internal/* root:bind /var/cache/bind/external/* 0644 /var/cache/bind/internal/* 0644 /var/cache/bind/external/* 19. Start the DNS server by typing /etc/init.d/bind9 start 20. That was a lot of typing and room for error so check the log for any errors: vi /var/log/daemon.log 21. Sanity check! At this point, if you type nslookup mail.mydomain.com, you should see that your internal DNS server (127.0.0.1) returned the result of your internal IP address (192.168.107.25 for your FQDN of mail.mydomain.com) 22. Sanity check! Type dig mydomain.com mx and make sure you see a status of NOERROR along with an MX record to your FQDN, NS record for your internal IP and an A record your FQDN to your internal IP. 23. Shutdown and power off the server by typing shutdown -P now {ENTER} 24. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 3 and description of Ubuntu Server 10.04.4 LTS, Split-DNS configured, Static IP: 192.168.107.25. Click OK. The Snapshot Manager should now have a nice hierarchy of snapshots (STEP 1 --> STEP 2 --> STEP 3 --> You are here) Final Ubuntu Changes 1. Start the Ubuntu server and connect using PuTTY. 2. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) 3. Update the package database by typing aptitude update 4. Install the latest updates by typing aptitude -y safe-upgrade 5. Shutdown and power off the server by typing shutdown -P now {ENTER} 6. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 4 and description of Ubuntu Server 10.04.4 LTS, all patches applied, Static IP: 192.168.107.25. The Snapshot Manager should now have a nice hierarchy of snapshots (STEP 1 --> STEP 2 --> STEP 3 --> STEP 4 --> You are here)
  • 35. 7. NOTE: Over time, upgrades to the kernel can start taking up space in /etc/src. I found this out because my root partition started to get full. When I typed this command: du sh /usr/src/* I found out there was over a gigabyte of old files. To cleanly clear out old an unused headers, type the following commands: Code: apt-get -f install apt-get autoremove __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) #7 (permalink) 04-26-2012, 07:32 PM LHammonds Special Member Posts: 138 Install Zimbra Install Zimbra NOTE: Install Zimbra by typing "./install.sh" and uninstall by typing "./install.sh -u" Prerequisite packages: NPTL sudo-1.7.2p1-1ubuntu5.3 libidn11-1.15-2 libpcre3-7.8-3build1 libgmp3c2-2:4.3.2+dfsg-1ubuntu1 libexpat1-2.0.1-7ubuntu1 libstdc++6-4.4.3-4ubuntu5 libperl5.10-5.10.1-8ubuntu2.1 Suggested prerequisites: perl-5.10.1 sysstat sqlite3 Install Procedure:
  • 36. 1. Start the Ubuntu server and connect using PuTTY. 2. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) 3. Download the Open Source Edition from Open Source Edition Downloads: Enterprise Messaging and Collaboration Software by Zimbra Method #1 - Download from your PC A. Download the .tgz file and copy it to the Ubuntu share --> mailshare or 192.168.107.25share B. Once copied to the server, access the console and type the following: Code: mv /srv/samba/share/zcs* /var/temp Method #2 - Download directly from the server A. Obtain the download URL from the Zimbra OSE page B. Type the following commands on the server console (using the correct URL) Code: cd /var/temp wget http://files.zimbra.com/downloads/7.2.0_GA/zcs7.2.0_GA_2669.UBUNTU10_64.20120410002303.tgz 4. Extract the archive by typing the following commands: Code: mkdir /var/temp/install tar -C /var/temp/install --strip-components=1 -xzf /var/temp/zcs* 5. Start the installation program by typing the following: Code: cd /var/temp/install ./install.sh 6. Agree to license agreement? Press y {ENTER} 7. If you are missing any prerequisites, exit the installation and install them. You can install all at one time by separating each name with a space after aptitude install such as the following:
  • 37. Code: aptitude -y install sysstat sqlite3 8. Install zimbra-ldap? Press y {ENTER} 9. Install zimbra-logger? Press y {ENTER} 10. Install zimbra-mta? Press y {ENTER} 11. Install zimbra-snmp? Press y {ENTER} 12. Install zimbra-store? Press y {ENTER} 13. Install zimbra-apache? Press y {ENTER} 14. Install zimbra-spell? Press y {ENTER} 15. Install zimbra-memcached? Press n {ENTER} (if multi-server, press y instead) 16. Install zimbra-proxy? Press n {ENTER} (if multi-server, press y instead) 17. The system will be modified. Continue? Press y {ENTER} 18. DNS ERROR resolving MX for mail.mydomain.com. Change domain name? Press y {ENTER} 19. Now we put the correct domain name in so type mydomain.com {ENTER} 20. You are presented a menu for resolving unconfigured options, press 3 {ENTER} 21. Select Admin password, press 4 {ENTER}. Then type your new password (myzimbrapass) {ENTER} 22. Press r {ENTER} for previous menu 23. Press a {ENTER} to apply changes. 24. Press y {ENTER}, {ENTER} to save configuration (/opt/zimbra/config.9066) 25. The system will be modified - continue? Press y {ENTER} 26. Notify Zimbra of your installation? Press n {ENTER} (feel free to answer yes if this is not a test system) 27. Press {ENTER} to exit setup. NOTE: Log files placed in /opt/zimbra/log 28. Shutdown and power off the server by typing the following: Code: /etc/init.d/zimbra stop shutdown -P now 29. In VM menu, select VM --> Snapshot --> Take Snapshot. Give it a name like STEP 5 and description of Ubuntu Server 10.04.4 LTS, Zimbra 7.2.0 OSE installed, Static IP: 192.168.107.25. The Snapshot Manager should now have a nice hierarchy of snapshots (STEP 1 --> STEP 2 --> STEP 3 --> STEP 4 --> STEP 5 --> You are here) Admin Console and Initial Test 1. Start the Ubuntu server. 2. Access the webmail control panel by opening a web browser and typing this in the address bar: https://192.168.107.25:7071 3. If your browser barks about an untrusted connection, tell it to continue anyway and add an exception for it so it will not have a problem with it next time. 4. Login as admin@mydomain.com / myrootpassword
  • 38. 5. Create a new user account. 6. When done creating a new user, open a new browser tab and access: http://192.168.107.25/ and login with your new user account. See if you can send an email! If it does not work, well, what can I say...you followed the advice of a Linux newbie. Scripted sendmail My scripts heavily reply upon the ability to send email notifications and this step will enable that ability. 1. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) 2. To configure the sendmail command to work with Zimbra, type the following: Code: update-alternatives --install /usr/sbin/sendmail mta-send /opt/zimbra/postfix/sbin/sendmail 25 3. Test sendmail by typing the following and then check your admin email to see if it is there: Code: sendmail -t{ENTER} to:admin@mydomain.com{ENTER} from:webmaster@mydomain.com{ENTER} subject: Test from Ubuntu sendmail{ENTER} {ENTER} Testing 1-2-3{ENTER} .{ENTER} Delete Snapshots Be sure to delete all snapshots when you are satisfied that you will no longer need to revert your installation to any of the prior snapshots. Zimbra and SSL Encryption I do not see a reason not to use SSL, especially if your user accounts and passwords match other systems such as Active Directory. A compromised email password can also
  • 39. compromise your network in that case. With that in mind, this is what I have done to make sure it is used at my location. If you just installed Zimbra, the installation process created a self-signed certificate. Step #1 - Enable SSL as the primary method of logging onto your server: 1. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) 2. At the server console, type the following to convert webmail to use encrypted https instead of http: Code: su - zimbra -c "zmtlsctl https" 3. For additional documentation, here is how you would switch back to non-SSL mode: Code: su - zimbra -c "zmtlsctl http" 4. For additional documentation, here is how you could use either SSL or non-SSL mode: Code: su - zimbra -c "zmtlsctl mixed" 5. Type reboot to reboot the server for the HTTPS change to take effect. Step #2 - Export the certificate for Windows. The certificate on the Zimbra server cannot be directly used by Windows and needs to be converted into a format that can be used. Do so using the following commands: Code: openssl x509 -in /opt/zimbra/ssl/zimbra/ca/ca.pem -out /srv/samba/share/cacert.der -outform DER chmod 0644 /srv/samba/share/cacert.der Step #3 - Import the certificate on Windows. For Windows machines, you might need to install the certificate manually to avoid Internet Explorer, MS Outlook and Google Chrome issues with self-signed certificates.
  • 40. Here are two methods for doing so. Method A - Domain Group Policy If you have a Windows domain, this is a very easy process to get all your machines to automatically accept the self-signed certificate on your Zimbra server. 1. 2. 3. 4. 5. On the domain controller, open Active Directory Users and Computers Right-click on your domain and select Properties Select the Group Policy tab Select the Default Domain Policy and click the Edit button Expand Computer Configuration --> Windows Settings --> Security Settings --> Public Key Policies 6. Right-click on Trusted Root Certification Authorities and click Import 7. Import Wizard - Click Next 8. Type the path to the cacert.der from your Zimbra server or click Browse (if you browse, you will need to change the file type to All Files in order to see the certificate file) and then click Next 9. Select Place all certificates in the following store --> Trusted Root Certification Authorities and click Next, Finish 10. The import was successful - Click OK 11. You should now see your mail server domain in the list. Example: mail.mydomain.com 12. Close Group Policy Object Editor and any other windows you opened Any Windows machine on your domain should now be able to open Internet Explorer and visit your SSL-enabled mail server without complaining about the self-signed certificate. Same goes for Outlook, Google Chrome and others. You may need to logout and log back in for the policy to take effect on the PCs. Method B - Manually Import the Certificate If you are forced to manually touch each PC by hand, here is how you can install the certificate (for Windows XP, Windows Vista or Windows 7) 1. Close Internet Explorer if it is open. 2. Click Start --> Run (or type in "Search programs and files" box on Windows 7) and type mmc to load an empty Microsoft Management Console. 3. If you receive a security warning, click the positive acknowledgement button (actual name varies all over the place). 4. From the menu, click File, Add / Remove Snap-In 5. Select Certificates and click the Add button 6. Select Computer account and click Next 7. Select Local computer and click Finish, OK 8. Expand Certificates, Trusted Root Certification Authorities and select the Certificates container 9. Right-click on the Certificates container, and choose the All Tasks --> Import 10. Import Wizard - Click Next 11. Type 192.168.107.25sharecacert.der and click Next
  • 41. 12. Select Place all certificates in the following store --> Trusted Root Certification Authorities and click Next, Finish 13. The import was successful - Click OK 14. Look in the list of certificates and you should see your domain such as mail.mydomain.com 15. Close the console (do not bother saving the MMC when asked) Step #4 - Update Your Certificate As time goes by, the certificate that was created with your installation will expire (360 days from install) and you will need to generate a new one. 1. At the login prompt, login with your administrator account (administrator / myadminpass) and then type su and the root password (myrootpass) 2. Type the commands below to generate a new self-signed certificate: Code: /opt/zimbra/bin/zmcertmgr /opt/zimbra/bin/zmcertmgr /opt/zimbra/bin/zmcertmgr /opt/zimbra/bin/zmcertmgr createca -new createcrt -new -days 365 deploycrt self deployca 3. Check to see if the certificate was deployed to all services by typing /opt/zimbra/bin/zmcertmgr viewdeployedcrt 4. Now go back through the above steps to export the new certificate and import into all your PCs Reference Article: Zimbra Wiki: Administration Console and CLI Certificate Tools __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) #8 (permalink) 04-26-2012, 07:43 PM LHammonds Special Member Posts: 138 Scripting Scripting Much of the solutions beyond this point involve scripts (programming snippets / automated commands).
  • 42. In particular, they are Bash Scripts. I chose this due to its popularity and the fact it comes with Ubuntu. I try to make use of what comes with the system without requiring additional software / services unless they really add to the bottom line such as decreasing the time it takes for a process to run or to conserve storage and bandwidth usage. When setting up a server and testing things out, there is typically very little concern for procedures / process since much of the activity is exploration and experimentation as well as not having an impact on production. However, once a server goes into production, processes and procedures need to be in place to ensure the availability of the services being provided. In regards to these scripts, they will be treated like any other program and will require being tested, documented and go through a promotion process. The ideal situation would involve 3 servers (for a single server setup). A test / development server, a quality assurance staging server and the production server itself. If 3 servers cannot be utilized, then it can still work well with 2 servers. Testing scripts / programs / restore on the production server is not advisable and many times impractical...how can you test your restore process / data periodically if you only have a production server? The QA Staging server would be as close to production as possible. The server should be setup in such a way that production backups are restored to this server which also tests and validates the backup / restore process as well as maintains a close representation of the production server to mitigate variable risk involved when testing new or modified programs and upgrades. The test / development server can serve as the QA server if absolutely necessary. The directory structure and how scripts can import other scripts will be configured to facilitate this process. Example: Directory path for scripts to import common variables, functions and server settings: /var/scripts/common/ Directory path for production scripts: /var/scripts/prod/ Directory path for QA staging area scripts: /var/scripts/qa/ Directory path for test / development scripts: /var/scripts/test/ With a production and test servers on physically different machines, the "common" scripts folder can be custom-tailored for that environment and allow for minimal changes to a script when running on the test, QA or production server. This is similar to "normalizing" a database. If you have a variable, path or function that is duplicated in multiple scripts, consider pulling it out and placing it in the common folder. If ever you need to change who receives the email reports, you only need to update a single script and all programs will use the new reference from that point on.
  • 43. Most of my scripts will import a file called "standard.conf" from the common script folder. /var/scripts/common/standard.conf (contents of the file on the production server) Code: ## Global Variables ## TEMPDIR="/var/temp" ZIMBRADIR="/opt/zimbra" SHAREDIR="/srv/samba/share" MYDOMAIN="mydomain.com" ADMINEMAIL="admin@${MYDOMAIN}" REPORTEMAIL="lhammonds@${MYDOMAIN}" BACKUPDIR="/var/backup" OFFSITEDIR="/mnt/backup" OFFSITETESTFILE="${OFFSITEDIR}/online.txt" ARCHIVEMETHOD="tar.7z" ## Choices are tar.7z or tgz HOSTNAME="$(hostname -s)" SCRIPTNAME="$0" SCRIPTDIR="/var/scripts" MAILFILE="${TEMPDIR}/mailfile.$$" ## Global Functions ## function f_sendmail() { ## Purpose: Send administrative email message. ## Parameter #1 = Subject ## Parameter #2 = Body echo "From: ${ADMINEMAIL}" > ${MAILFILE} echo "To: ${REPORTEMAIL}" >> ${MAILFILE} echo "Subject: ${1}" >> ${MAILFILE} echo "" >> ${MAILFILE} echo -e "${2}" >> ${MAILFILE} echo "" >> ${MAILFILE} echo -e "nnServer: ${HOSTNAME}nProgram: ${SCRIPTNAME}nLog: ${LOGFILE}" >> ${MAILFILE} sendmail -t < ${MAILFILE} rm ${MAILFILE} } function f_sendusermail() { ## Purpose: Send end-user email message. ## Parameter #1 = To ## Parameter #2 = Subject ## Parameter #3 = Body echo "From: ${ADMINEMAIL}" > ${MAILFILE} echo "To: ${1}" >> ${MAILFILE} echo "Subject: ${2}" >> ${MAILFILE} echo "" >> ${MAILFILE} echo -e "${3}" >> ${MAILFILE} sendmail -t < ${MAILFILE} rm ${MAILFILE} } function f_mount() { ## Mount the pre-configured Windows share folder.
  • 44. ## NOTE: The Windows share should have a file called "online.txt" mount -t cifs //srv-backup/zimbra ${OFFSITEDIR} --options nouser,rw,nofail,noatime,noexec,credentials=/etc/cifspw } function f_umount() { ## Dismount the Windows share folder. ## NOTE: The unmounted folder should have a file called "offline.txt" umount ${OFFSITEDIR} } /var/scripts/common/standard.conf (contents of the file on the test server) Code: ## Global Variables ## TEMPDIR="/tmp" ZIMBRADIR="/opt/zimbra800" SHAREDIR="/srv/samba/share" MYDOMAIN="mytestdomain.com" ADMINEMAIL="test1@${MYDOMAIN}" REPORTEMAIL="test2@${MYDOMAIN}" BACKUPDIR="/var/backup" OFFSITEDIR="/mnt/fakedir" OFFSITETESTFILE="${OFFSITEDIR}/online.txt" ARCHIVEMETHOD="tar.7z" ## Choices are tar.7z or tgz HOSTNAME="$(hostname -s)" SCRIPTNAME="$0" SCRIPTDIR="/var/scripts/" MAILFILE="${TEMPDIR}/mailfile.$$" ## Global Functions ## function f_sendmail() { ## Purpose: Send administrative email message. ## Parameter #1 = Subject ## Parameter #2 = Body echo "From: ${ADMINEMAIL}" > ${MAILFILE} echo "To: ${REPORTEMAIL}" >> ${MAILFILE} echo "Subject: ${1}" >> ${MAILFILE} echo "" >> ${MAILFILE} echo -e "${2}" >> ${MAILFILE} echo "" >> ${MAILFILE} echo -e "nnServer: ${HOSTNAME}nProgram: ${SCRIPTNAME}nLog: ${LOGFILE}" >> ${MAILFILE} sendmail -t < ${MAILFILE} rm ${MAILFILE} } function f_sendusermail() { ## Purpose: Send end-user email message. ## Parameter #1 = To ## Parameter #2 = Subject ## Parameter #3 = Body echo "From: ${ADMINEMAIL}" > ${MAILFILE} echo "To: ${1}" >> ${MAILFILE} echo "Subject: ${2}" >> ${MAILFILE}
  • 45. echo "" >> ${MAILFILE} echo -e "${3}" >> ${MAILFILE} sendmail -t < ${MAILFILE} rm ${MAILFILE} } function f_mount() { ## Mount the pre-configured Windows share folder. ## NOTE: The Windows share should have a file called "online.txt" mount -t cifs //mypc/zimbra ${OFFSITEDIR} --options nouser,rw,nofail,noatime,noexec,credentials=/etc/cifspw } function f_umount() { ## Dismount the Windows share folder. ## NOTE: The unmounted folder should have a file called "offline.txt" umount ${OFFSITEDIR} } When receiving email notifications, the server name, script name and path will be included at the bottom of the email every time. It will be readily apparent if the email was generated from the test, qa or production server simply because of the location (even if test, qa and production are all on the same server). Here are the scripts to help automate the creation of this structure on the various servers (would run all of them if all are the same box) setup-script-prod.sh Code: #!/bin/bash if [ ! -d /var/scripts/prod ]; then mkdir -p /var/scripts/prod fi if [ ! -d /var/scripts/common ]; then mkdir -p /var/scripts/common fi chown root:root /var/scripts chown root:root /var/scripts/prod chown root:root /var/scripts/common chmod 0777 /var/scripts chmod 0755 /var/scripts/prod chmod 0755 /var/scripts/common setup-script-qa.sh Code: #!/bin/bash if [ ! -d /var/scripts/qa ]; then mkdir -p /var/scripts/qa fi if [ ! -d /var/scripts/common ]; then mkdir -p /var/scripts/common fi
  • 46. chown chown chown chmod chmod chmod root:root /var/scripts root:root /var/scripts/qa root:root /var/scripts/common 0777 /var/scripts 0777 /var/scripts/qa 0755 /var/scripts/common setup-script-test.sh Code: #!/bin/bash if [ ! -d /var/scripts/test ]; then mkdir -p /var/scripts/test fi if [ ! -d /var/scripts/common ]; then mkdir -p /var/scripts/common fi chown root:root /var/scripts chown root:root /var/scripts/test chown root:root /var/scripts/common chmod 0777 /var/scripts chmod 0777 /var/scripts/test chmod 0777 /var/scripts/common __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) Last edited by LHammonds; 05-05-2012 at 12:07 PM.. #9 (permalink) 04-26-2012, 07:48 PM LHammonds Special Member Posts: 138 Keep Zimbra in Sync with Active Directory For my scenario, I want mailboxes created automatically when I create an Active Directory (AD) account. I do not want the mailbox to authenticate against AD though. To accomplish this, two or three scripts will be created and setup to run on a regular basis. The 1st script will be run on a Windows server and will create a comma-delimited (CSV) file for all users who belong to a security group called "GRP_ZimbraEmail" which allows me to selectively pick who is allowed to have a mailbox. The script will probably just run once per day (after hours). The CSV file will be placed on Ubuntu's Samba share. The 2nd script will be running on Ubuntu and checking for the input file very often (every minute). It will then cycle through all the AD users and see which users do not have a mailbox account and then create the mailbox using the supplied details.
  • 47. export_zimbra_ad_users.vbs Code: Option Explicit '**************************************** '** Name: export_zimbra_ad_users.vbs '** Version: 1.1 '** Date: 2011-10-29 '** Author: LHammonds '** Purpose: Export AD users to a comma-delimited file '** that are authorized to have a Zimbra mailbox. '**************************************** '* Field #1 = LoginID '* Field #2 = First Name '* Field #3 = Middle Initial '* Field #4 = Last Name '* Field #5 = Full Name '* Field #6 = Title '* Field #7 = Description '* Field #8 = Comments '* Field #9 = Telephone '* Field #10 = Home Phone '* Field #11 = Mobile Phone '* Field #12 = Fax Number '* Field #13 = Pager '* Field #14 = Company '* Field #15 = Office '* Field #16 = Street Address '* Field #17 = PO Box '* Field #18 = City '* Field #19 = State '* Field #20 = Postal Code '* Field #21 = Country '* Field #22 = Password Replacement Value '* Field #23 = Unused (mainly to avoid the end-of-line character being read into the last value) '** NOTE: This could use a data cleanup routine that replaces all commas in a ** '** variable with something else such as a period instead to avoid CSV issues. ** Const Const Const Const ForAppending = 8 FilePath = "D:Reportsadlist.csv" ZimbraSecurityGroup = "GRP_ZimbraEmail" DefaultPassword = "ChangeThisPassword" Dim objRootDSE, strDNC, objDomain, objFSO, objFile Set objRootDSE = GetObject("LDAP://RootDSE") strDNC = objRootDSE.Get("DefaultNamingContext") Set objDomain = GetObject("LDAP://" & strDNC) '** Create / Overwrite the export file. ** Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(FilePath) objFile.Close Set objFile = Nothing
  • 48. Call TrollTheFolders(objDomain) Sub TrollTheFolders(pobjDomain) '** Function: Traverse the AD structure to find users wherever they may reside. ** '** The trick is that this function is called recursively in order to ** '** inspect every sub-folder that may contain user accounts. ** Dim lobjFile, lobjFSO, lobjMember, lstrLine, lblnInZimbraGroup Dim lstrSamAccountName, lstrFirstName, lstrInitials, lstrLastName Dim lstrFullName, lstrTitle, lstrDescription, lstrComment Dim lstrTelephoneNumber, lstrHomePhone, lstrMobile, lstrFaxNumber, lstrPager Dim lstrCompany, lstrOffice, lstrStreetAddress, lstrPostOfficeBox Dim lstrCity, lstrState, lstrPostalCode, lstrCountry, lstrPassword Dim lcolGroups, lobjGroup, lstrTemp For Each lobjMember In pobjDomain '** Examine each object but process only "user" objects. ** If lobjMember.Class = "user" Then Set lobjFile = objFSO.OpenTextFile (FilePath, ForAppending, True) If Not (isempty(lobjMember.samAccountName)) Then lstrSamAccountName = lobjMember.samAccountName Else lstrSamAccountName = "" End If If Not (isempty(lobjMember.GivenName)) Then lstrFirstName = lobjMember.GivenName Else lstrFirstName = "" End If If Not (isempty(lobjMember.initials)) Then lstrInitials = lobjMember.initials Else lstrInitials = "" End If If Not (isempty(lobjMember.sn)) Then lstrLastname = lobjMember.sn Else lstrLastName = "" End If If Not (isempty(lobjMember.CN)) Then lstrFullName = lobjMember.CN Else lstrFullName = "" End If If Not (isempty(lobjMember.title)) Then lstrTitle = lobjMember.title Else lstrTitle = "" End If If Not (isempty(lobjMember.Description)) Then lstrDescription = lobjMember.Description Else lstrDescription = "" End If If Not (isempty(lobjMember.comment)) Then lstrComment = lobjMember.comment Else lstrComment = "" End If If Not (isempty(lobjMember.telephoneNumber)) Then lstrTelephoneNumber = lobjMember.telephoneNumber Else lstrTelephoneNumber = "" End If If Not (isempty(lobjMember.homePhone)) Then lstrHomePhone = lobjMember.homePhone Else lstrHomePhone = "" End If If Not (isempty(lobjMember.mobile)) Then lstrMobile = lobjMember.mobile Else lstrMobile = "" End If If Not (isempty(lobjMember.otherFacsimileTelephoneNumber)) Then lstrFaxNumber = lobjMember.otherFacsimileTelephoneNumber Else lstrFaxNumber = "" End If If Not (isempty(lobjMember.pager)) Then lstrPager = lobjMember.pager Else lstrPager = "" End If If Not (isempty(lobjMember.company)) Then lstrCompany = lobjMember.company Else lstrCompany = "" End If If Not (isempty(lobjMember.physicalDeliveryOfficeName)) Then lstrOffice = lobjMember.physicalDeliveryOfficeName Else lstrOffice = "" End If If Not (isempty(lobjMember.streetAddress)) Then lstrStreetAddress = lobjMember.streetAddress Else lstrStreetAddress = "" End If If Not (isempty(lobjMember.postOfficeBox)) Then lstrPostOfficeBox = lobjMember.postOfficeBox Else lstrPostOfficeBox = "" End If If Not (isempty(lobjMember.l)) Then lstrCity = lobjMember.l Else lstrCity = "" End If
  • 49. If Not (isempty(lobjMember.st)) Then lstrState = lobjMember.st Else lstrState = "" End If If Not (isempty(lobjMember.postalCode)) Then lstrPostalCode = lobjMember.postalCode Else lstrPostalCode = "" End If If Not (isempty(lobjMember.countryCode)) Then lstrCountry = lobjMember.countryCode Else lstrCountry = "" End If lstrPassword = DefaultPassword lblnInZimbraGroup = 0 For Each lobjGroup in lobjMember.Groups '** See if this member belongs to the group that allows Zimbra mailboxes ** If LCase(lobjGroup.cn) = LCase(ZimbraSecurityGroup) Then lblnInZimbraGroup = 1 End If Next If lblnInZimbraGroup = 1 Then '** Member is associated to the Zimbra Email group and thus allowed to have a Zimbra mailbox. ** lstrLine = lstrSamAccountName & "," & lstrFirstName & "," & lstrInitials & "," & lstrLastName & "," & lstrFullName & "," &_ lstrTitle & "," & lstrDescription & "," & lstrComment & "," & lstrTelephoneNumber & "," & lstrHomePhone & "," & lstrMobile & "," &_ lstrFaxNumber & "," & lstrPager & "," & lstrCompany & "," & lstrOffice & "," & lstrStreetAddress & "," & lstrPostOfficeBox & "," &_ lstrCity & "," & lstrState & "," & lstrPostalCode & "," & lstrCountry & "," & lstrPassword & ",unused" lobjFile.WriteLine(lstrLine) End If lobjFile.Close Set lobjFile = Nothing End If If lobjMember.Class = "organizationalUnit" or lobjMember.Class = "container" Then '** Recurse further down to find the users. ** TrollTheFolders(lobjMember) End If Next End Sub Sample adlist.csv Code: mmouse,Mickey,,Mouse,Mickey Mouse,,Lab Assistant,,,,,,800-8675309,,,,,,,,0,ChangeThisPassword,unused jdirt,Joe,,Dirt,Joe Dirt,Chief Information Officer,Chief Information Officer,,800-555-5555,,,,,ABC,Information Systems,404 Hollywood Street,,Hollywood,CA,90210,840,ChangeThisPassword,unused ddiggler,Dirk,,Diggler,Dirk Diggler,Database Administrator,IS-Database Administrator,,800-555-0404,800-789-1234,888-111-2222,,,,Information Systems,404 Cowboy Country Road,,Hickville,TX,77501,840,ChangeThisPassword,unused jdoe,John,,Doe,John Doe,System Analyst,IS-Telco Systems Analyst,,800-9998888,,,,,,Information Systems,666 Gov Road,,Washington,WA,10110,840,ChangeThisPassword,unused import-ad.sh Code: #!/bin/bash
  • 50. ############################################# ## Name : import-ad.sh ## Version : 1.2 ## Date : 2011-11-02 ## Author : LHammonds ## Purpose : Add mailbox accounts for AD users that have none. ## Compatibility : Verified on Ubuntu Server 10.04.3 - 10.04.4 LTS, Zimbra 7.1.2 - 7.2.0 OSE ## Requirements : Zimbra must be online, must be run as root user. ## Run Frequency : Run very frequently (every minute) ## Exit Codes : ## 0 = Success ## 1 = Failure ################ CHANGE LOG ################# ## DATE WHO WHAT WAS CHANGED ## ---------- --- ---------------------------## 2011-10-11 LTH Created script. ## 2011-10-29 LTH Better logging, mail support, bug fixes. ## 2011-11-02 LTH Moved standard variables/functions to external file. ############################################# ## Import standard variables and functions. ## source /var/scripts/common/standard.conf LOGFILE="${TEMPDIR}/import-ad.log" MAILFILE="${TEMPDIR}/import-ad-mail.$$" ADLISTORG="${SHAREDIR}/adlist.csv" ADLISTNEW="${TEMPDIR}/import-ad-adlist.$$" ZMUSERS="${TEMPDIR}/import-ad-zmuserlist.$$" ZMCMD="${TEMPDIR}/import-ad-zmcmd.$$" NEWUSERS="" RETURNVALUE=0 ## Temporarily change the default field separator to a comma. # OLDIFS="${IFS}" IFS="," ## If the Active Directory user list file is not found, exit the script. # if [ ! -f ${ADLISTORG} ]; then ## No file to process. Exit script. exit 0 fi echo "`date +%Y-%m-%d_%H:%M:%S` - Active Directory file found! Import process started." >> ${LOGFILE} ## Create files and set permissions for only the root user. # touch ${ZMCMD} touch ${ZMUSERS} chmod 0600 ${ZMCMD} chmod 0600 ${ZMUSERS} ## Take ownership and set permissions for only the root user. # chown root:root ${ADLISTORG} chmod 0400 ${ADLISTORG} ## Move the file to a working folder. # mv ${ADLISTORG} ${ADLISTNEW} ## Create a list of users in Zimbra for the specified domain. # ${ZIMBRADIR}/bin/zmprov -l getAllAccounts ${MYDOMAIN} > ${ZMUSERS} ## Loop through the Active Directory user list. # while read -a ADLINE ; do
  • 51. ## Slot 0 = UserID ## Slot 1 = First Name (GivenName) ## Slot 2 = Initials ## Slot 3 = Last Name (sn) ## Slot 4 = Full Name (CN) ## Slot 5 = Title ## Slot 6 = Description ## Slot 7 = Comment ## Slot 8 = Telephone / Work Number ## Slot 9 = Home Phone ## Slot 10 = Mobile Phone ## Slot 11 = Fax Number (facsimileTelephoneNumber) ## Slot 12 = Pager ## Slot 13 = Company ## Slot 14 = Office (physicalDeliveryOfficeName) ## Slot 15 = Street Address ## Slot 16 = Post Office Box ## Slot 17 = City (l) ## Slot 18 = State (st) ## Slot 19 = Postal Code ## Slot 20 = Country Code (co) ## Slot 21 = Password ## Set the "Found Match" variable to false # FOUND=0 ## Loop through the Zimbra User List. # while read -a ZMLINE ; do ## Convert Usernames to lower case. # ZMUSERID=${ZMLINE[0],,} ADUSERID=${ADLINE[0],,} ## Add domain address to the end of the AD Username # ADUSERID=${ADUSERID}"@"${MYDOMAIN} ## Compare the lowercase AD username to the lower case Zimbra username. # if [ ${ADUSERID} == ${ZMUSERID} ]; then ## Match found. Exit this while loop. # FOUND=1 break fi done < ${ZMUSERS} if [ ${FOUND} -eq 0 ]; then ## We have an AD user that does not have a Zimbra mailbox. # NEWUSERS="${NEWUSERS}${ADLINE[0]}@${MYDOMAIN}n" echo "`date +%Y-%m-%d_%H:%M:%S` --- Adding new user: ${ADLINE[0]}@${MYDOMAIN}" >> ${LOGFILE} echo "createAccount ${ADLINE[0]}@${MYDOMAIN} "${ADLINE[21]}" gn "${ADLINE[1]}" initials "${ADLINE[2]}" sn "${ADLINE[3]}" cn "${ADLINE[4]}" title "${ADLINE[5]}" description "${ADLINE[6]}" zimbraNotes "${ADLINE[7]}" telephoneNumber "${ADLINE[8]}" homePhone "${ADLINE[9]}" mobile "${ADLINE[10]}" facsimileTelephoneNumber "${ADLINE[11]}" pager "${ADLINE[12]}" company "${ADLINE[13]}" physicalDeliveryOfficeName "${ADLINE[14]}" street "${ADLINE[15]}" postOfficeBox "${ADLINE[16]}" l "${ADLINE[17]}" st "${ADLINE[18]}" postalCode "${ADLINE[19]}" co "${ADLINE[20]}"">> ${ZMCMD} fi done < ${ADLISTNEW} ## If the Zimbra command file is not empty, we need to process it. # if [ -s ${ZMCMD} ]; then ${ZIMBRADIR}/bin/zmprov < ${ZMCMD} 1>/dev/null 2>&1 RETURNVALUE=$?
  • 52. if [ ${RETURNVALUE} -ne 0 ]; then ## Something went wrong with the mailbox creation. ## This error should notify administrators to the problem. echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: zmprov reported the following error: ${RETURNVALUE}" >> ${LOGFILE} echo "`date +%Y-%m-%d_%H:%M:%S` - Import aborted. EXIT CODE = 1" >> ${LOGFILE} f_sendmail "Zimbra Active Directory Import" "ERROR: zmprov reported the following error: ${RETURNVALUE}nnRemaining temporary files:n${ZMUSERS}n${ZMCMD}n${ADLISTNEW}n" exit 1 fi ## Send email notification of the new users added to Zimbra. # ## NOTE: To be 100% sure about this, we could loop through the users # ## and verify that they now have Zimbra mailboxes. # f_sendmail "Zimbra Notification - New Users" "The following users were added to Zimbra:nn${NEWUSERS}" else ## There were no new users to process. # echo "`date +%Y-%m-%d_%H:%M:%S` --- No new users to import." >> ${LOGFILE} fi echo "`date +%Y-%m-%d_%H:%M:%S` - Active Directory import completed." >> ${LOGFILE} ## Restore the default field separator value. # IFS="${OLDIFS}" ## rm rm rm Remove temporary files. # ${ZMUSERS} ${ZMCMD} ${ADLISTNEW} Sample email when new mailboxes are created: Code: Subject: Zimbra Notification - New Users The following users were added to Zimbra: ddiggler@mydomain.com jdoe@mydomain.com jsmith@mydomain.com lhammonds@mydomain.com mmouse@mydomain.com Server: mail Program: /var/scripts/prod/import-ad.sh Log: /var/temp/import-ad.log Here is a sample log file (NOTE: There are no entries if no file is found): Code: 2011-10-29_17:06:49 2011-10-29_17:06:52 2011-10-29_17:06:53 2011-10-29_17:06:53 2011-10-29_17:06:53 2011-10-29_17:06:53 - Active Directory file found! Import process started. --- Adding new user: ddiggler@mydomain.com --- Adding new user: jdoe@mydomain.com --- Adding new user: jsmith@mydomain.com --- Adding new user: lhammonds@mydomain.com --- Adding new user: mmouse@mydomain.com
  • 53. 2011-10-29_17:06:56 2011-10-29_17:07:29 2011-10-29_17:07:32 2011-10-29_17:07:32 - Active Directory import completed. - Active Directory file found! Import process started. --- No new users to import. - Active Directory import completed. If you keep a database of all your user's IDs and passwords, you could export that information to the Linux box and have it safely tucked away and used in-between the AD Export and AD Import process. It could run through the AD user list and replace the default password with their existing password making it operate seamlessly within the environment. If user passwords are unknown, the process would be to let the individual know their mailbox was created with a standard password and that they need to login and change it ASAP. Reference Articles: zmprov command-line documentation Bash Guide NOTE: If you like this solution, you might also want to review the modified version by digidt in my older thread. __________________ Type su - zimbra -c "zmcontrol -v" to get your version and copy that into your profile (more info here) #10 (permalink) 04-26-2012, 07:50 PM LHammonds Special Member Posts: 138 Global Address List for iPhones Global Address List for iPhones I have a working solution in place for our iPhone users to access the Internal Global Address List (GAL) when they start a new email message and click the "To" button to show a list of all contacts in our company (not just personal contacts). Normally, you will only get a list of contacts in your personal folder. I have tried various ways to get this to work such as sharing the _InternalGAL folder but could not get anything to work well. I certainly do not want to give my users the credentials to the galsync account (which is my admin account). This method uses a service account (dummy mailbox) to hold a copy of the GAL. Each iPhone user then adds an additional CardDAV account and enters the shared account's details. For this example, I created a mailbox called "addresslist@mydomain.com" and then logged
  • 54. into that account and shared the contacts folder as "Public" for anyone to access. Next, login to the admin console, expand Configuration --> Domains and click on mydomain.com. Click the Configure GAL button. Set the following and click Next, Finish: GAL mode: Internal Most results returned by GAL search: 250 Use GAL Sync account (recommended): Check GAL sync account name: admin@mydomain.com (or whatever galsync account you want) Datasource name for internal GAL: InternalGAL Internal GAL polling interval: 1 days Next, force the initial sync by typing the following at the Ubuntu console as the root user: Code: su - zimbra -c "zmgsautil forceSync -a admin@mydomain.com -n InternalGAL" If you login to the web mail client and login with the galsync (admin) account, you should see the "_InternalGAL" folder under the Address Book tab and it should be populated with your internal users. Before the account can be backed up with the script below, the services need to be restarted. Code: /etc/init.d/zimbra stop /etc/init.d/zimbra start Now setup the script below to run on a regular schedule which will backup the GAL Sync's "_InternalGAL" folder to an archive. It will then extract the archive and change references of "_InternalGAL" to "Contacts" in all files so it can be restored in a folder that the iPhone will recognize. Then it is re-packed into an archive and restored to the "addresslist" account which completely replaces whatever is in the "Contacts" folder with the updated list. As an additional step, it will delete specific addresses which are not desired to show up in the global list. Also note that this is not necessary on the Pro Network Edition which has an iPhone sync utility. gal-sync.sh Code: #!/bin/bash ############################################# ## Name : gal-sync.sh ## Version : 1.1 ## Date : 2011-11-02 ## Author : LHammonds ## Compatibility : Ubuntu Server 10.04.3 - 10.04.4 LTS, Zimbra 7.1.3 7.2.0 OSE ## Requirements : Zimbra must be online, must be run as root user. ## Purpose : Expose Internal GAL (Global Address List) for use on
  • 55. iPhones ## Run Frequency : Once per day (after hours preferable but not necessary) ## Exit Codes : (if multiple errors, value is the addition of codes) ## 0 = success ## 1 = security failure ## 2 = zmmailbox getRestURL failure ## 4 = zmmailbox postRestURL failure ## 8 = zmmailbox getAllContacts failure ## 16 = tar extraction failure ## 32 = tar creation failure ################# CHANGE LOG ################# ## DATE WHO WHAT WAS CHANGED ## ---------- --- ---------------------------## 2011-10-28 LTH Created script. ## 2011-10-31 LTH Added check for root ID. ## 2011-11-02 LTH Moved standard variables / functions to external file. ## NOTE: Should add detection of address list account. ############################################## ## Import common variables and functions. ## source /var/scripts/common/standard.conf GALSYNCACCT="admin@${MYDOMAIN}" PUBLICGALACCT="addresslist@${MYDOMAIN}" EXCEPTIONS="addresslist@${MYDOMAIN};admin@${MYDOMAIN};test@${MYDOMAIN};test 2@${MYDOMAIN}" GALSYNCDIR="${TEMPDIR}/galsync" LOGFILE="${TEMPDIR}/gal-sync.log" CONTACTFILE="${TEMPDIR}/gal-sync-contact.$$" GALARCHIVE1="galsync1.tgz" GALARCHIVE2="galsync2.tgz" CONTACTNUMDEL=0 CONTACTNUMALL=0 RETURNVALUE=0 ERRORFLAG=0 ####################################### ## FUNCTIONS ## ####################################### function f_cleanup() { ## Purpose: Cleanup files and folders used by the script. if [ -d ${GALSYNCDIR} ]; then rm -rf ${GALSYNCDIR} fi if [ -f ${TEMPDIR}/${GALARCHIVE1} ]; then rm ${TEMPDIR}/${GALARCHIVE1} fi if [ -f ${TEMPDIR}/${GALARCHIVE2} ]; then rm ${TEMPDIR}/${GALARCHIVE2} fi if [ -f ${CONTACTFILE} ]; then rm ${CONTACTFILE} fi } function f_emergencyexit()
  • 56. { ## Purpose: Exit script as cleanly as possible. ## Parameter #1 = Error Code. f_cleanup f_sendmail "Zimbra iPhone GAL Sync Error" "EXIT CODE = ${1}" echo "`date +%Y-%m-%d_%H:%M:%S` - GAL Sync aborted. EXIT CODE: ${1}" >> ${LOGFILE} ## Write script name and error code to the system log. logger "${SCRIPTNAME}: ERROR CODE = ${1}" exit $1 } ####################################### ## MAIN PROGRAM ## ####################################### echo "`date +%Y-%m-%d_%H:%M:%S` - GAL Sync started." >> ${LOGFILE} ## Requirement Check: Script must run as root user. if [ "$(id -u)" != "0" ]; then ## FATAL ERROR DETECTED: Document problem and terminate script. echo "`date +%Y-%m-%d_%H:%M:%S` - GAL Sync aborted. ERROR: Root user required." >> ${LOGFILE} ERRORFLAG=$((${ERRORFLAG} + 1)) f_emergencyexit ${ERRORFLAG} fi ## Backup the global address listing. ${ZIMBRADIR}/bin/zmmailbox -z -m ${GALSYNCACCT} getRestURL "/_InternalGAL?fmt=tgz" > ${TEMPDIR}/${GALARCHIVE1} RETURNVALUE=$? if [ ${RETURNVALUE} -ne 0 ]; then ## FATAL ERROR DETECTED: Document problem and terminate script. echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: ${ZIMBRADIR}/bin/zmmailbox -z -m ${GALSYNCACCT} getRestURL '/_InternalGAL?fmt=tgz'" >> ${LOGFILE} echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >> ${LOGFILE} ERRORFLAG=$((${ERRORFLAG} + 2)) f_emergencyexit ${ERRORFLAG} fi ## Prepare the extraction folder and set appropriate permissions. mkdir -p ${GALSYNCDIR} chmod 0600 ${GALSYNCDIR} ## Extract the archive to modify its contents. tar -xf ${TEMPDIR}/${GALARCHIVE1} -C ${GALSYNCDIR} 1>/dev/null 2>&1 RETURNVALUE=$? if [ ${RETURNVALUE} -ne 0 ]; then ## FATAL ERROR DETECTED: Document problem and terminate script. echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: tar -xf ${TEMPDIR}/${GALARCHIVE1} -C ${GALSYNCDIR}" >> ${LOGFILE} echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >> ${LOGFILE} ERRORFLAG=$((${ERRORFLAG} + 16)) f_emergencyexit ${ERRORFLAG} fi ## Search and replace all meta data occurances of "_InternalGAL" with "Contacts" ## This will allow the contacts to be restored to the "Contacts" folder.
  • 57. sed -i 's/_InternalGAL/Contacts/g' ${GALSYNCDIR}/*.meta sed -i 's/_InternalGAL/Contacts/g' ${GALSYNCDIR}/_InternalGAL/*.meta ## Count the number of meta files (contacts) in the GAL folder. CONTACTNUMALL=`ls -1 ${GALSYNCDIR}/_InternalGAL/*.meta | wc -l` ## Create a new archive with the modified data. tar -czf ${TEMPDIR}/${GALARCHIVE2} ${GALSYNCDIR} 1>/dev/null 2>&1 RETURNVALUE=$? if [ ${RETURNVALUE} -ne 0 ]; then ## FATAL ERROR DETECTED: Document problem and terminate script. echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: tar -czf ${TEMPDIR}/${GALARCHIVE2} ${GALSYNCDIR}" >> ${LOGFILE} echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >> ${LOGFILE} ERRORFLAG=$((${ERRORFLAG} + 32)) f_emergencyexit ${ERRORFLAG} fi ## Replace contacts in the iPhone GAL account. ${ZIMBRADIR}/bin/zmmailbox -z -m ${PUBLICGALACCT} postRestURL "//?fmt=tgz&resolve=reset" ${TEMPDIR}/${GALARCHIVE2} RETURNVALUE=$? if [ ${RETURNVALUE} -ne 0 ]; then ## FATAL ERROR DETECTED: Document problem and terminate script. echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: ${ZIMBRADIR}/bin/zmmailbox -z -m ${PUBLICGALACCT} postRestURL '//?fmt=tgz&resolve=reset'" >> ${LOGFILE} echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >> ${LOGFILE} ERRORFLAG=$((${ERRORFLAG} + 4)) f_emergencyexit ${ERRORFLAG} fi ## Export all contacts to a working file to determine which contacts to remove. ${ZIMBRADIR}/bin/zmmailbox -z -m ${PUBLICGALACCT} getAllContacts > ${CONTACTFILE} RETURNVALUE=$? if [ ${RETURNVALUE} -ne 0 ]; then ## FATAL ERROR DETECTED: Document problem and terminate script. echo "`date +%Y-%m-%d_%H:%M:%S` --- ERROR: ${ZIMBRADIR}/bin/zmmailbox -z -m ${PUBLICGALACCT} getAllContacts" >> ${LOGFILE} echo "`date +%Y-%m-%d_%H:%M:%S` --- Return Value: ${RETURNVALUE}" >> ${LOGFILE} ERRORFLAG=$((${ERRORFLAG} + 8)) f_emergencyexit ${ERRORFLAG} fi ## Obtain list of Contact IDs with matching email addresses in the exception list. while read LINEID LINEVALUE; do if [ "${LINEID}" = "Id:" ]; then CURRID=${LINEVALUE} fi if [ "${LINEID}" = "email:" ]; then ## Determine if this is an email address that we are looking for. if `echo ${EXCEPTIONS} | grep -q "${LINEVALUE}"` then ## Found a contact to remove from the address book. ## Verify that the contact ID is an integer.