Repository: Zimbra/zm-build Branch: develop Commit: 8b669aab1a4d Files: 148 Total size: 1.0 MB Directory structure: gitextract_jdedxgo8/ ├── .circleci/ │ ├── ENVIRONMENT.txt │ ├── config.yml │ ├── jobs/ │ │ └── deploy_ec2/ │ │ ├── deploy.sh │ │ ├── install.conf.in │ │ └── upgrade.conf.in │ └── misc/ │ ├── glean_version.pl │ └── status_api.sh ├── .gitignore ├── .project ├── RE/ │ ├── MICRO_WIN │ ├── README.txt │ └── RELEASE ├── README.md ├── build.pl ├── config.build.in ├── instructions/ │ ├── .gitignore │ ├── FOSS_package_list.pl │ ├── FOSS_remote_list.pl │ ├── FOSS_repo_list.pl │ ├── FOSS_staging_list.pl │ └── bundling-scripts/ │ ├── .gitignore │ ├── utils.sh │ ├── zcs-bundle.sh │ ├── zimbra-apache.sh │ ├── zimbra-core.sh │ ├── zimbra-dnscache.sh │ ├── zimbra-imapd.sh │ ├── zimbra-ldap.sh │ ├── zimbra-logger.sh │ ├── zimbra-mta.sh │ ├── zimbra-proxy.sh │ ├── zimbra-snmp.sh │ ├── zimbra-spell.sh │ └── zimbra-store.sh ├── lib/ │ └── Zimbra/ │ ├── DB/ │ │ └── DB.pm │ ├── LDAP.pm │ ├── LocalConfig.pm │ ├── Mon/ │ │ ├── Logger.pm │ │ ├── LoggerSchema.pm │ │ └── Zmstat.pm │ ├── SMTP.pm │ ├── SOAP/ │ │ ├── Soap.pm │ │ ├── Soap11.pm │ │ ├── Soap12.pm │ │ ├── XmlDoc.pm │ │ └── XmlElement.pm │ ├── Util/ │ │ ├── Common.pm │ │ ├── LDAP.pm │ │ └── Timezone.pm │ └── ZmClient.pm ├── rpmconf/ │ ├── Build/ │ │ ├── checkLicense.pl │ │ ├── checkService.pl │ │ ├── create_distribution.dist.sh │ │ ├── get_plat_tag.sh │ │ └── zmValidateLdap.pl │ ├── Conf/ │ │ ├── auditswatchrc │ │ ├── hotspot_compiler │ │ ├── logswatchrc │ │ ├── mibs/ │ │ │ ├── zimbra.mib │ │ │ └── zimbra_traps.mib │ │ ├── snmp.conf │ │ ├── snmpd.conf.in │ │ ├── swatchrc │ │ └── zmssl.cnf.in │ ├── Ctl/ │ │ ├── zimbra.cf.in │ │ ├── zimbracore.cf │ │ ├── zimbraldap.cf │ │ ├── zimbralogger.cf │ │ ├── zimbramail.cf │ │ ├── zimbramta.cf │ │ └── zimbrasnmp.cf │ ├── Env/ │ │ ├── crontabs/ │ │ │ ├── crontab │ │ │ ├── crontab.ldap │ │ │ ├── crontab.logger │ │ │ ├── crontab.mta │ │ │ └── crontab.store │ │ ├── sudoers.d/ │ │ │ ├── 01_zimbra │ │ │ ├── 02_zimbra-core │ │ │ ├── 02_zimbra-dnscache.deb │ │ │ ├── 02_zimbra-dnscache.rpm │ │ │ ├── 02_zimbra-mta │ │ │ └── 02_zimbra-store │ │ ├── zimbra.bash_profile │ │ ├── zimbra.bashrc │ │ ├── zimbra.exrc │ │ ├── zimbra.ldaprc │ │ ├── zimbra.platform │ │ └── zimbra.viminfo │ ├── Install/ │ │ ├── Util/ │ │ │ ├── addUser.sh │ │ │ ├── globals.sh │ │ │ ├── modules/ │ │ │ │ ├── getconfig.sh │ │ │ │ ├── packages.sh │ │ │ │ └── postinstall.sh │ │ │ └── utilfunc.sh │ │ ├── install.sh │ │ ├── postinstall.pm │ │ ├── preinstall.pm │ │ ├── test.pl │ │ └── zmsetup.pl │ ├── LicenseTool/ │ │ ├── Zimbra/ │ │ │ ├── Customer.pm │ │ │ ├── License.pm │ │ │ ├── LicenseKey.pm │ │ │ └── LicensingDB.pm │ │ ├── db/ │ │ │ └── create_license_db.sql │ │ └── zmlicensetool.pl │ ├── Patch/ │ │ ├── bin/ │ │ │ └── zmpatch.pl │ │ ├── conf/ │ │ │ └── zmpatch.xml │ │ ├── installPatch.sh │ │ └── libexec/ │ │ ├── zmcurl807-updater.sh │ │ └── zmopenssl-updater.sh │ ├── Spec/ │ │ ├── Scripts/ │ │ │ ├── zimbra-core.post │ │ │ ├── zimbra-core.pre │ │ │ ├── zimbra-dnscache.post │ │ │ ├── zimbra-ldap.post │ │ │ ├── zimbra-logger.post │ │ │ ├── zimbra-mta.post │ │ │ ├── zimbra-proxy.post │ │ │ ├── zimbra-qa.post │ │ │ ├── zimbra-snmp.post │ │ │ ├── zimbra-spell.post │ │ │ ├── zimbra-store.post │ │ │ └── zimbra-store.pre │ │ ├── zimbra-apache.deb │ │ ├── zimbra-apache.spec │ │ ├── zimbra-core.deb │ │ ├── zimbra-core.spec │ │ ├── zimbra-dnscache.deb │ │ ├── zimbra-dnscache.spec │ │ ├── zimbra-imapd.deb │ │ ├── zimbra-imapd.spec │ │ ├── zimbra-ldap.deb │ │ ├── zimbra-ldap.spec │ │ ├── zimbra-logger.deb │ │ ├── zimbra-logger.spec │ │ ├── zimbra-mta.deb │ │ ├── zimbra-mta.spec │ │ ├── zimbra-proxy.deb │ │ ├── zimbra-proxy.spec │ │ ├── zimbra-qa.deb │ │ ├── zimbra-qa.spec │ │ ├── zimbra-snmp.deb │ │ ├── zimbra-snmp.spec │ │ ├── zimbra-spell.deb │ │ ├── zimbra-spell.spec │ │ ├── zimbra-store.deb │ │ └── zimbra-store.spec │ └── Upgrade/ │ └── zmupgrade.pm └── show_git_overrides.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .circleci/ENVIRONMENT.txt ================================================ ENV VARIABLES: (used by deploy_ec2@app1_install, deploy_ec2@app1_upgrade): APP1_ADMIN_PASS = password to set admin user to. APP1_SSH_HOST = ec2 machine APP1_SSH_USER = ec2 username (with sudo) (used by deploy_ec2@app2_install, deploy_ec2@app2_upgrade): APP2_ADMIN_PASS = password to set admin user to. APP2_SSH_HOST = ec2 machine APP2_SSH_USER = ec2 username (with sudo) SSH PERMISSIONS: (used by deploy_ec2) (private key for ec2 machine named in $APP1_SSH_HOST above) (private key for ec2 machine named in $APP2_SSH_HOST above) AWS PERMISSIONS: (used by deploy_s3) Access Key ID Secret Access Key ================================================ FILE: .circleci/config.yml ================================================ # vim:expandtab:ts=3 version: 2 ############################################################################ references: checkout_job_steps: &checkout_job_steps steps: - checkout - run: name: Checking out dependencies command: | mkdir -p ../BUILDS ./build.pl \ --build-type=FOSS \ --build-hostname=build.zimbra.org \ --build-release="$CIRCLE_PROJECT_USERNAME" \ --build-release-no=$(.circleci/misc/glean_version.pl) \ --build-release-candidate=beta \ --build-thirdparty-server=zdev-vm008.eng.zimbra.com \ --deploy-url-prefix="https://files.zimbra.com/dev-releases/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$CIRCLE_BRANCH-$CIRCLE_BUILD_NUM" \ --git-default-branch="$CIRCLE_BRANCH,develop" \ --build-os="UBUNTU16_64" \ --pkg-os-tag="u16" \ --build-no="$CIRCLE_BUILD_NUM" \ --build-ts="$(date "+%Y%m%d%M%H%S")" \ --ant-options="-DskipTests=1" \ --no-interactive \ --disable-bundle \ --dump-config-to="$PWD/config.build" \ --stop-after-checkout \ --exclude-git-repos=zm-timezones \ 2>&1 \ | tee ../BUILDS/checkout.log; # FIXME: remove this hack, and fix --dump-config-to sed -i \ -e '/^DUMP_CONFIG_TO/d' \ -e '/^STOP_AFTER_CHECKOUT/d' \ -e '/^INTERACTIVE/d' \ -e '/^BUILD_OS/d' \ -e '/^PKG_OS_TAG/d' \ -e '/^BUILD_ARCH/d' \ -e '/\/d' \ -e '/\/d' \ config.build; - persist_to_workspace: root: ../.. paths: - checkout - .zcs-deps build_job_steps: &build_job_steps steps: - attach_workspace: at: ../.. - run: name: Creating build command: | rm ../BUILDS/checkout.log ENV_GIT_UPDATE_INCLUDE=@ \ ./build.pl 2>&1 \ --build-os="$ZIMBRA_BUILD_OS" \ --pkg-os-tag="$ZIMBRA_OS_TAG" \ --no-interactive \ | tee -a ../BUILDS/build-${ZIMBRA_OS_TAG}.log - store_artifacts: path: ../BUILDS - persist_to_workspace: root: ../.. paths: checkout/BUILDS deploy_s3_job_steps: &deploy_s3_job_steps steps: - attach_workspace: at: ../.. - deploy: name: Deploying to S3 command: | for i in ../BUILDS/* do if [ -d "$i" ] then # NOTE: We are not using $CIRCLE_BUILD_NUM as its different for each job of the workflow # Instead, we need $CIRCLE_BUILD_NUM allocated for 'checkout' job, (stored in config.build) BUILD_NO=$(cat config.build | sed -ne '/^BUILD_NO\>/ { s/.*=\s*//p }'); [ ! -z "$BUILD_NO" ] || exit 2; aws s3 sync "$i" "s3://files.zimbra.com/dev-releases/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$CIRCLE_BRANCH-$BUILD_NO/" \ --acl public-read \ --region us-east-1 fi done deploy_ec2_job_steps: &deploy_ec2_job_steps steps: - attach_workspace: at: ../.. - deploy: name: Deploying to EC2 command: | MY_SSH_HOST_var="${EC2_TARGET}_SSH_HOST"; MY_SSH_USER_var="${EC2_TARGET}_SSH_USER"; MY_ADMIN_PASS_var="${EC2_TARGET}_ADMIN_PASS"; .circleci/jobs/deploy_ec2/deploy.sh \ -o ${OPERATION} \ -t ${PKG_OS_TAG} \ -h ${!MY_SSH_HOST_var} \ -u ${!MY_SSH_USER_var} \ -a ${!MY_ADMIN_PASS_var} std_filters: &std_filters filters: branches: only: - master - develop ############################################################################ jobs: checkout: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail docker: - image: zimbra/zm-base-os:devcore-ubuntu-16.04 <<: *checkout_job_steps build_u16: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - ZIMBRA_OS_TAG: u16 - ZIMBRA_BUILD_OS: UBUNTU16_64 docker: - image: zimbra/zm-base-os:devcore-ubuntu-16.04 <<: *build_job_steps build_u14: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - ZIMBRA_OS_TAG: u14 - ZIMBRA_BUILD_OS: UBUNTU14_64 docker: - image: zimbra/zm-base-os:devcore-ubuntu-14.04 <<: *build_job_steps build_u12: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - ZIMBRA_OS_TAG: u12 - ZIMBRA_BUILD_OS: UBUNTU12_64 docker: - image: zimbra/zm-base-os:devcore-ubuntu-12.04 <<: *build_job_steps build_r7: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - ZIMBRA_OS_TAG: r7 - ZIMBRA_BUILD_OS: RHEL7_64 docker: - image: zimbra/zm-base-os:devcore-centos-7 <<: *build_job_steps build_r6: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - ZIMBRA_OS_TAG: r6 - ZIMBRA_BUILD_OS: RHEL6_64 docker: - image: zimbra/zm-base-os:devcore-centos-6 <<: *build_job_steps deploy_s3: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail docker: - image: zimbra/zm-base-os:core-ubuntu <<: *deploy_s3_job_steps deploy_ec2@app1_install: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - EC2_TARGET: APP1 - OPERATION: install - PKG_OS_TAG: u16 docker: - image: zimbra/zm-base-os:core-ubuntu <<: *deploy_ec2_job_steps deploy_ec2@app1_upgrade: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - EC2_TARGET: APP1 - OPERATION: upgrade - PKG_OS_TAG: u16 docker: - image: zimbra/zm-base-os:core-ubuntu <<: *deploy_ec2_job_steps deploy_ec2@app2_install: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - EC2_TARGET: APP2 - OPERATION: install - PKG_OS_TAG: r6 docker: - image: zimbra/zm-base-os:core-ubuntu <<: *deploy_ec2_job_steps deploy_ec2@app2_upgrade: working_directory: ~/checkout/zm-build shell: /bin/bash -euo pipefail environment: - EC2_TARGET: APP2 - OPERATION: upgrade - PKG_OS_TAG: r6 docker: - image: zimbra/zm-base-os:core-ubuntu <<: *deploy_ec2_job_steps ############################################################################ workflows: version: 2 main: jobs: - checkout ######################### - build_u16: requires: - checkout - build_u14: requires: - checkout - build_u12: requires: - checkout # - build_r7: # requires: # - checkout - build_r6: requires: - checkout ######################### - deploy_s3_hold: type: approval requires: - build_u16 - build_u14 - build_u12 # - build_r7 (core dump issue while running ant) - build_r6 <<: *std_filters - deploy_s3: requires: - deploy_s3_hold <<: *std_filters ######################### - app1_ec2_install: type: approval requires: - build_u16 <<: *std_filters - app1_ec2_upgrade: type: approval requires: - build_u16 <<: *std_filters - deploy_ec2@app1_install: requires: - app1_ec2_install <<: *std_filters - deploy_ec2@app1_upgrade: requires: - app1_ec2_upgrade <<: *std_filters ######################### - app2_ec2_install: type: approval requires: - build_r6 <<: *std_filters - app2_ec2_upgrade: type: approval requires: - build_r6 <<: *std_filters - deploy_ec2@app2_install: requires: - app2_ec2_install <<: *std_filters - deploy_ec2@app2_upgrade: requires: - app2_ec2_upgrade <<: *std_filters ================================================ FILE: .circleci/jobs/deploy_ec2/deploy.sh ================================================ #!/bin/bash set -euo pipefail SCRIPT_DIR=$(CDPATH= cd "$(dirname "$0")" && pwd); CIRCLE_DIR=$(dirname "$(dirname "$SCRIPT_DIR")") usage() { echo "Usage: $0 -o -t -h -u -a " 1>&2; echo 1>&2; echo "Example:" 1>&2; echo " $0 -o upgrade -t u16 -h ec2-xx-xx-xx-xx.us-east-2.compute.amazonaws.com -u ubuntu -a admin123" 1>&2; exit 1 } ####################################################################### ##### PARSE ARGS, SANITIZE ##### ####################################################################### set +u while getopts "o:t:h:u:a:" cur_opt; do case "${cur_opt}" in o) OPERATION="${OPTARG}" if [ "$OPERATION" != "upgrade" ] && [ "$OPERATION" != "install" ] then usage fi ;; t) PKG_OS_TAG=${OPTARG} case "$PKG_OS_TAG" in u16) DIR=$(echo $CIRCLE_DIR/../../BUILDS/UBUNTU16_64* | head -1); ;; u14) DIR=$(echo $CIRCLE_DIR/../../BUILDS/UBUNTU14_64* | head -1); ;; u12) DIR=$(echo $CIRCLE_DIR/../../BUILDS/UBUNTU12_64* | head -1); ;; r7) DIR=$(echo $CIRCLE_DIR/../../BUILDS/RHEL7_64* | head -1); ;; r6) DIR=$(echo $CIRCLE_DIR/../../BUILDS/RHEL6_64* | head -1); ;; *) usage; ;; esac ;; h) MY_SSH_HOST=${OPTARG} ;; u) MY_SSH_USER=${OPTARG} ;; a) MY_ADMIN_PASS=${OPTARG} ;; *) usage ;; esac done shift $((OPTIND-1)) if [ -z "$MY_SSH_USER" ] || [ -z "$MY_SSH_HOST" ] || [ -z "$MY_ADMIN_PASS" ] || [ -z "$PKG_OS_TAG" ] then usage; fi if [ ! -f "$CIRCLE_DIR/config.yml" ] then echo "Rerun from within .circleci directory"; exit 1 fi if [ ! -d "$DIR" ] then echo "Could not find the BUILD"; exit 1; fi set -u ##### END GETOPT ##### ####################################################################### ####################################################################### ##### RSYNC ##### ####################################################################### SSH_OPTS=( "-o" "UserKnownHostsFile=/dev/null" "-o" "StrictHostKeyChecking=no" "-o" "CheckHostIP=no" "-o" "ServerAliveInterval=100" ) Rsync() { rsync -e "ssh ${SSH_OPTS[*]}" "$@" } Ssh() { ssh "${SSH_OPTS[@]}" "$@" } #Rsync --delete -avz $CIRCLE_DIR/../zm-build "$MY_SSH_USER@$MY_SSH_HOST:" Rsync --delete -avz "$DIR/" "$MY_SSH_USER@$MY_SSH_HOST:BUILD/" Rsync $CIRCLE_DIR/jobs/deploy_ec2/install.conf.in "$MY_SSH_USER@$MY_SSH_HOST:BUILD/install.conf.in" Rsync $CIRCLE_DIR/jobs/deploy_ec2/upgrade.conf.in "$MY_SSH_USER@$MY_SSH_HOST:BUILD/upgrade.conf.in" ##### END RSYNC ##### ####################################################################### ####################################################################### ##### FORWARD SCRIPT TO EXECUTE ##### ####################################################################### Ssh "$MY_SSH_USER@$MY_SSH_HOST" -- tee /tmp/injected_bash_script.sh <<"SCRIPT_EOM" #!/bin/bash [ -z "$DOMAIN_NAME" ] && echo "DOMAIN_NAME is not defined" && exit 1; [ -z "$ADMIN_PASS" ] && echo "ADMIN_PASS is not defined" && exit 1; [ -z "$OPERATION" ] && echo "OPERATION is not defined" && exit 1; [ -z "$PKG_OS_TAG" ] && echo "PKG_OS_TAG is not defined" && exit 1; set -euxo pipefail setUp() { echo ----------------------------------- echo System Setup specific to EC2 echo ----------------------------------- [ -f /etc/hosts.orig ] || sudo cp /etc/hosts /etc/hosts.orig [ -f /etc/resolv.conf.orig ] || sudo cp /etc/resolv.conf /etc/resolv.conf.orig EC2_IP=$(hostname | sed -e 's/[.\s].*$//' -e 's/^ip-//' -e 's/[-]/./g') EC2_RESOLVE=$(hostname | sed -e 's/[.\s].*$//' -e 's/^ip-//' -e 's/[-]/./g' -e 's/[.][0-9]*[.][0-9]*$/.0.2/') sudo sed -i -e "\$a$EC2_IP $(hostname -f) $(hostname)" -e "/ip-/ { /$(hostname)/d; }" /etc/hosts sudo sed -i -e "/^search/i\\nameserver $EC2_RESOLVE\nnameserver 8.8.8.8" -e "/nameserver 8.8.8.8/d" -e "/nameserver $EC2_RESOLVE/d" /etc/resolv.conf echo ----------------------------------- echo System Cleanup echo ----------------------------------- set +e; sudo killall master zmstat-fd sudo killall -u zimbra sudo killall -u postfix sudo pkill -f 'amavi[s]' sleep 10 sudo killall -9 master zmstat-fd sudo killall -9 -u zimbra sudo killall -9 -u postfix sudo pkill -9 -f 'amavi[s]' sleep 10 [[ "$PKG_OS_TAG" =~ u* ]] && sudo apt-get remove --purge -y zimbra-* [[ "$PKG_OS_TAG" =~ r* ]] && sudo yum erase -y zimbra-* sudo rm -rf /opt/zimbra [[ "$PKG_OS_TAG" =~ u* ]] && sudo apt-get install -y perl [[ "$PKG_OS_TAG" =~ r* ]] && sudo yum install -y perl if [[ "$PKG_OS_TAG" =~ r6 ]] then if [ ! -f /usr/lib/python2.6/site-packages/yum/__init__.py.patched ] then #We are running into a curious yum bug - See https://bugzilla.redhat.com/show_bug.cgi?id=993567 sudo yum -y install wget patch sudo wget http://s3.amazonaws.com/files.zimbra.com/dev-releases/hold/r6-yum-patch/yum.patch -O ~/yum.patch sudo cp /usr/lib/python2.6/site-packages/yum/__init__.py{,.orig} sudo patch -p0 < ~/yum.patch sudo cp /usr/lib/python2.6/site-packages/yum/__init__.py{,.patched} fi fi echo } buildCleanUp() { echo ----------------------------------- echo Build Cleanup, Uncompress new tarball echo ----------------------------------- sudo rm -rf ~/WDIR mkdir ~/WDIR tar -C ~/WDIR -xzf BUILD/zcs-*.tgz } prepareConfig() { echo ----------------------------------- echo Create install configuration echo ----------------------------------- HOSTNAME="$(hostname --fqdn)" RESOLVE="$(cat /etc/resolv.conf | awk '/^\s*nameserver/ { print $2; }' | grep -v ^127 | head -1)" sed -e "s/template_resolv/$RESOLVE/" \ -e "s/template_hostname/$HOSTNAME/" \ -e "s/template_domainname/$DOMAIN_NAME/" \ -e "s/template_admin_pass/$ADMIN_PASS/g" \ ~/BUILD/install.conf.in > ~/WDIR/install.conf cat ~/BUILD/upgrade.conf.in > ~/WDIR/upgrade.conf } updatePackages() { echo ----------------------------------- echo Setup local archives echo ----------------------------------- if [[ "$PKG_OS_TAG" =~ u ]] then sudo rm -f /etc/apt/sources.list.d/zimbra-*.list echo "deb [trusted=yes] file://$(echo $HOME/BUILD/archives/*/$PKG_OS_TAG) ./" | sudo tee -a /etc/apt/sources.list.d/zimbra-local.list echo "deb [trusted=yes] https://files.zimbra.com/dev-releases/hold/Zimbra/zm-zextras/develop-52/archives/zimbra-zextras/$PKG_OS_TAG ./" | sudo tee -a /etc/apt/sources.list.d/zimbra-zextras.list echo "deb [trusted=yes] https://files.zimbra.com/dev-releases/hold/Zimbra/zm-timezones/develop-35/archives/zimbra-foss/$PKG_OS_TAG ./" | sudo tee -a /etc/apt/sources.list.d/zimbra-foss.list #echo "deb [arch=amd64] https://repo.zimbra.com/apt/zimbra-zextras xenial zimbra" | sudo tee -a /etc/apt/sources.list.d/zimbra-zextras.list #echo "deb [arch=amd64] https://repo.zimbra.com/apt/zimbra-foss xenial zimbra" | sudo tee -a /etc/apt/sources.list.d/zimbra-foss.list sudo apt-get update -qq fi if [[ "$PKG_OS_TAG" =~ r ]] then sudo rm -f /etc/yum.repos.d/zimbra-*.repo sudo tee -a /etc/yum.repos.d/zimbra-local.repo <) { if ( $_ =~ /refs.*\/release\/([0-9]+[.][0-9]+[.])([0-9]+)/ ) { my $nV = $1 . ( $2 + 1 ); if( ( version->parse($nV) <=> version->parse($V) ) gt 0 ) { $V = $nV; } } } close(FD); print $V . "\n" } ================================================ FILE: .circleci/misc/status_api.sh ================================================ #!/bin/bash set -e -o pipefail curl -Ls "https://circleci.com/api/v1.1/project/github/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/$CIRCLE_BUILD_NUM?circle-token=$CIRCLE_API_TOKEN" ================================================ FILE: .gitignore ================================================ .build.last_no_ts .build.number .idea config.build RE/BUILD RE/MAJOR RE/MICRO RE/MINOR ================================================ FILE: .project ================================================ ZimbraBuild ================================================ FILE: RE/MICRO_WIN ================================================ 1_M1 ================================================ FILE: RE/README.txt ================================================ Included: Binary release: README.txt - this file install.sh - install script bin/ - binaries used during install data/ - contains installation data packages/ - contains ZCS rpms docs/ - more documentation Source release: README.txt - this file src/ - source files docs/ - more documentation Installing from binary: tar xzf zcs.tgz cd zcs ./install.sh Installing from source: Consult the file readme_source.txt ================================================ FILE: RE/RELEASE ================================================ 1 ================================================ FILE: README.md ================================================ # zm-build ## Introduction This repository contains the build script and supporting files required to create a [FOSS](https://en.wikipedia.org/wiki/Free_and_open-source_software) build of the [Zimbra Collaboration Suite](https://www.zimbra.com/). ## Overview * `build.pl` - Invoke this script to produce a build. See the *Building* section below for an example. * `instructions/` * `FOSS_remote_list.pl` - Maps between remote label and URL * `FOSS_repo_list.pl` - Specifies which branches (or tags) are checked out to build each component repository. * `FOSS_staging_list.pl` - defines the staging order and details. ## Setup with Zimbra Development Images (used for building) * Set up docker on your box * You can then pull and run using development images (built from Zimbra/zm-base-os.git) * In case you need to customize the images for your purposes, you could maintain your own Dockerfile such as this: $ cat Dockerfile FROM zimbra/zm-base-os:devcore-ubuntu-16.04 RUN sudo apt-get install emacs my-special-tool etc.. RUN ... $ docker build -t myuser/my-devcore-ubuntu-16 . $ docker run -it myuser/my-devcore-ubuntu-16 bash ### Ubuntu 16.04 docker run -it zimbra/zm-base-os:devcore-ubuntu-16.04 bash ### CentOS 7 docker run -it zimbra/zm-base-os:devcore-centos-7 bash ### CentOS 6 docker run -it zimbra/zm-base-os:devcore-centos-6 bash # some tools are installed inside /home/build/.zm-dev-tools/, zm-build automatically sources this path. ## Setup (traditional) ### Ubuntu 16.04 The following steps assume that your are starting with a clean VM and are logged in as a non-root user with `sudo` privileges. sudo apt-get update sudo apt-get install software-properties-common openjdk-8-jdk ant ant-optional ant-contrib ruby git maven build-essential debhelper ### CentOS 7 sudo yum groupinstall 'Development Tools' sudo yum install java-1.8.0-openjdk ant ant-junit ruby git maven cpan wget perl-IPC-Cmd ### CentOS 6 sudo yum groupinstall 'Development Tools' sudo yum remove java-1.7.0-openjdk java-1.6.0-openjdk ant sudo yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel ruby git cpan wget # install specific perl modules sudo cpan IPC::Cmd cd /tmp # install maven wget http://mirror.metrocast.net/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz sudo tar -xf apache-maven-3.3.9-bin.tar.gz sudo mv apache-maven-3.3.9 /opt echo 'export PATH="/opt/apache-maven-3.3.9/bin:$PATH"' | sudo tee -a /etc/profile.d/maven.sh # install current version of ant wget https://www.apache.org/dist/ant/binaries/apache-ant-1.9.9-bin.zip sudo unzip apache-ant-1.9.9-bin.zip sudo mv apache-ant-1.9.9 /opt echo 'export PATH="/opt/apache-ant-1.9.9/bin:$PATH"' | sudo tee -a /etc/profile.d/ant.sh ## Building Create a directory for your build and check-out the `zm-build` repository: Build from develop branch mkdir installer-build cd installer-build git clone https://github.com/Zimbra/zm-build.git cd zm-build git checkout origin/develop ENV_CACHE_CLEAR_FLAG=true ./build.pl --ant-options -DskipTests=true --ant-options -DskipCoverage=true --ant-options -DskipSonarScan=true --git-default-branch=develop --build-release-no=10.1.0 --build-type=FOSS --build-release=LIBERTY --build-release-candidate=GA --build-thirdparty-server=files.zimbra.com --no-interactive Build 10.1.0 ``` mkdir installer-build cd installer-build git clone --depth 1 --branch 10.1.0 git@github.com:Zimbra/zm-build.git cd zm-build ENV_CACHE_CLEAR_FLAG=true ./build.pl --ant-options -DskipTests=true --git-default-tag=10.1.0 --build-release-no=10.1.0 --build-type=FOSS --build-release=LIBERTY --build-release-candidate=GA --build-thirdparty-server=files.zimbra.com --no-interactive ``` To build a specific patch example 10.0.8 run the following: ``` mkdir installer-build cd installer-build git clone --depth 1 --branch 10.0.6 git@github.com:Zimbra/zm-build.git cd zm-build ENV_CACHE_CLEAR_FLAG=true ./build.pl --ant-options -DskipTests=true --git-default-tag=10.0.8,10.0.7,10.0.6,10.0.5,10.0.4,10.0.3,10.0.2,10.0.1,10.0.0-GA --build-release-no=10.0.8 --build-type=FOSS --build-release=LIBERTY --build-release-candidate=GA --build-thirdparty-server=files.zimbra.com --no-interactive ``` Or for example 9.0.0.p40 run the following: ``` mkdir installer-build cd installer-build git clone --depth 1 --branch 9.0.0.p38 git@github.com:Zimbra/zm-build.git cd zm-build ENV_CACHE_CLEAR_FLAG=true ./build.pl --ant-options -DskipTests=true --git-default-tag=9.0.0.p40,9.0.0.p39,9.0.0.p38,9.0.0.p37,9.0.0.p36,9.0.0.p35,9.0.0.p34,9.0.0.p33,9.0.0.p32.1,9.0.0.p32,9.0.0.p31,9.0.0.p30,9.0.0.p29,9.0.0.p28,9.0.0.p27,9.0.0.p26,9.0.0.p25,9.0.0.p24.1,9.0.0.p24,9.0.0.p23,9.0.0.p22,9.0.0.p21,9.0.0.p20,9.0.0.p19,9.0.0.p18,9.0.0.p17,9.0.0.p16,9.0.0.p15,9.0.0.p14,9.0.0.p13,9.0.0.p12,9.0.0.p11,9.0.0.p10,9.0.0.p9,9.0.0.p8,9.0.0.p7,9.0.0.p6.1,9.0.0.p6,9.0.0.p5,9.0.0.p4,9.0.0.p3,9.0.0.p2,9.0.0.p1,9.0.0 --build-release-no=9.0.0 --build-type=FOSS --build-release=KEPLER --build-release-candidate=GA --build-thirdparty-server=files.zimbra.com --no-interactive ``` The `build.pl` command is used to build the product. Run it with the `-h` option for help: Usage: ./build.pl Supported options: --build-no=i --build-ts=i --build-artifacts-base-dir=s --build-sources-base-dir=s --build-release=s --build-release-no=s --build-release-candidate=s --build-type=s --build-thirdparty-server=s --build-prod-flag! --build-debug-flag! --build-dev-tool-base-dir=s --interactive! --git-overrides=s% --git-default-tag=s --git-default-remote=s --git-default-branch=s --stop-after-checkout! You _can_ specify all the options on the command-line, as follows: ./build.pl --build-no=1713 --build-ts=`date +'%Y%m%d%H%M%S'` \ --build-release=JUDASPRIEST --build-release-no=8.7.6 \ --build-release-candidate=GA --build-type=FOSS \ --build-thirdparty-server=files.zimbra.com --no-interactive The completed build will be archived into a `*.tgz` file that is stored in the appropriate platform and release-specific subdirectory of the `BUILDS` directory. The above command, run on an Ubuntu 16.04 machine, created the following: $HOME/installer_build/BUILDS/UBUNTU16_64/JUDASPRIEST-876/20170322153033_FOSS/zm-build/zcs-8.7.6_1713.UBUNTU16_64.20170322153033.tgz You can also specify any or all of the required options by placing them in a file called `config.build`. This file should be at the top level of the `zm-build` directory. For example: BUILD_NO = 1713 BUILD_RELEASE = JUDASPRIEST BUILD_RELEASE_NO = 8.7.6 BUILD_RELEASE_CANDIDATE = GA BUILD_TYPE = FOSS BUILD_THIRDPARTY_SERVER = files.zimbra.com INTERACTIVE = 0 Then just run `./build.pl`. The above command, run on a CentOS 7 machine with the options as shown in `config.build`, created the following: $HOME/installer-build/BUILDS/RHEL7_64/JUDASPRIEST-876/20170323061131_FOSS/zm-build/zcs-8.7.6_GA_1713.RHEL7_64.20170323061131.tgz # Development ## Setup The following is a walk-through of the basic steps required to do ZCS development. The first step is to simply install a current FOSS build on the machine that you wish to use. The instructions that follow assume that this has been done. 1. Create `/home/zimbra` and make `zimbra` the owner. sudo mkdir /home/zimbra sudo chown zimbra:zimbra /home/zimbra 2. Install `git`, `ant`, and `ant-contrib` by whichever method is appropriate for your distro: sudo apt-get install git ant ant-contrib or sudo yum install git ant ant-contrib 3. Configure `/opt/zimbra/.ssh/config` to use your ssh key for the git remotes that you need to access. 4. Perform the following edits on `/opt/zimbra/.bash_profile` * Comment-out `export LANG=C` and `export LC_ALL=C`. * Add export `LANG=en_US.UTF-8` * Add export `ANT_OPTS=-Ddev.home=/home/zimbra` 5. Change permissions on files and folders that you will be updating; e.g., sudo chmod -R o+w /opt/zimbra/lib/ sudo chmod -R o+w /opt/zimbra/jetty/ sudo chown zimbra:zimbra /opt/zimbra **Note:** If you run `zmfixperms`, some of these permissions will be overwritten. 6. Add file `/opt/zimbra/.gitconfig` and update as needed. At a minimum: [user] email = YOUR-EMAIL-ADDRESS name = YOUR-FIRST-AND-LAST-NAME 7. As the `zimbra` user, create a base directory under `/home/zimbra` from which to work. cd /home/zimbra mkdir zcs cd zcs 8. Now you can clone any repositories that you require and get to work. ## Email Delivery If you want email delivery to work, set up a DNS server on your host machine or another VM and configure `zimbraDNSMasterIP` to point to it. To configure `zimbraDNSMasterIP`, do the following as the `zimbra` user: zmprov ms `zmhostname` zimbraDNSMasterIP DNS-SERVER-IP-ADDRESS You may receive the following error when trying to send email: No SMTP hosts available for domain If this occurs, you need to manually configure `zimbraSmtpHostname` for your domain(s). To configure `zimbraSmtpHostname`, do the following as the `zimbra` user: zmprov md DOMAIN-NAME zimbraSmtpHostname `zmhostname` ## zm-mailbox example As the `zimbra` user, `cd /home/zimbra/zcs`. Then clone the `zm-mailbox` repository from github git clone git@github.com:Zimbra/zm-mailbox.git The following sub-directories `zm-mailbox` build and deploy separately: client common milter-conf native soap store store-conf The top-level `build.xml` is used by the `zm-build` scripts to create an installer package. You will not use that for normal development. There are build-order dependencies between the above-listed deployment targets. These can be determined by inspection of the `ivy.xml` files within each subdirectory. For example: grep 'org="zimbra"' store/ivy.xml Here you can see that the deployment target, `zm-store` (the `store` subdirectory), depends upon `common`, `soap`, `client`, and `native`. Here is the current ordering dependencies among all of the `zm-mailbox` deployment targets. The higher-numbered deployment targets depend upon the lower-numbered ones. Note that `milter-conf` and `store-conf` have no cross-dependencies. 1. `native` 2. `common` 3. `soap` 4. `client` 5. `store` So, from the `native` sub-directory: ant -Dzimbra.buildinfo.version=8.7.6_GA clean compile publish-local deploy Comments: - The requirement to include `-Dzimbra.buildinfo.version=8.7.6_GA` to ant is due to a change that was made when the FOSS code was moved to GitHub. You can also just add that option to your `ANT_OPTS` enviroment variable that you defined in `$HOME/.bash_profile` as follows: export ANT_OPTS="-Ddev.home=/home/zimbra -Dzimbra.buildinfo.version=8.7.6_GA" If you do that, then you can omit that `-D...` argument to the `ant` command and future examples will reflect that. - The `publish-local` target adds the artifact to `/home/zimbra/.zcs-deps`, which is included in the Ivy resolution path. - The `deploy` target installs the artifact to its run-time location and restarts the appropriate service(s). This will allow you to test your changes. Then, from the `common`, `soap`, `client`, and `store` sub-directories (in that order): ant clean compile publish-local deploy ## Adding a new LDAP Attribute **WARNING:It is absolutely imperative to avoid duplicate IDs for attributes. Unfortunately, that currently isn't a trivial thing to do. Need to check Zimbra 8 and Zimbra X along with all development branches. If customers get different setups using different IDs, this makes future upgrade scenarios a complete nightmare** Start by cloning _both_ the `zm-ldap-utilites` and the `zm-mailbox` repositories from GitHub. Check out the appropriate branch of each. Then proceed as follows: * Add your new attribute to `zm-mailbox/store/conf/attrs/zimbra-attrs.xml` * From `zm-common/store` invoke the following command: ant generate-getters * Do the following as `root`: chmod -R o+w /opt/zimbra/common/etc/openldap/schema chmod o+w /opt/zimbra/conf/zimbra.ldif chmod +w /opt/zimbra/conf/attrs/zimbra-attrs.xml chmod -R o+w /opt/zimbra/common/etc/openldap/zimbra * Back as the `zimbra` user, invoke the following command from `zm-mailbox/common`: ant deploy publish-local * Then from the `zm-mailbox/store` directory: ant deploy update-ldap-schema Your ZCS development server should now be running with the new attribute(s). You can test that by querying them and modifying them with `zmprov`. You can `git add ...` and `git commit` your changes now. ================================================ FILE: build.pl ================================================ #!/usr/bin/perl use strict; use warnings; use Config; use Cwd; use Data::Dumper; use File::Basename; use File::Copy; use Getopt::Long; use IPC::Cmd qw/run/; use Net::Domain; use Term::ANSIColor; my $GLOBAL_PATH_TO_SCRIPT_FILE; my $GLOBAL_PATH_TO_SCRIPT_DIR; my $GLOBAL_PATH_TO_TOP; my $CWD; my %CFG = (); BEGIN { $ENV{ANSI_COLORS_DISABLED} = 1 if ( !-t STDOUT ); $GLOBAL_PATH_TO_SCRIPT_FILE = Cwd::abs_path(__FILE__); $GLOBAL_PATH_TO_SCRIPT_DIR = dirname($GLOBAL_PATH_TO_SCRIPT_FILE); $GLOBAL_PATH_TO_TOP = dirname($GLOBAL_PATH_TO_SCRIPT_DIR); $CWD = getcwd(); } chdir($GLOBAL_PATH_TO_TOP); ############################################################################################## sub LoadConfiguration($) { my $args = shift; my $cfg_name = $args->{name}; my $cmd_hash = $args->{hash_src}; my $default_sub = $args->{default_sub}; my @cfg_list = (); push( @cfg_list, "config.build" ); push( @cfg_list, ".build.last_no_ts" ) if ( $ENV{ENV_RESUME_FLAG} ); my $val; my $src; if ( !defined $val ) { y/A-Z_/a-z-/ foreach ( my $cmd_name = $cfg_name ); if ( $cmd_hash && exists $cmd_hash->{$cmd_name} ) { $val = $cmd_hash->{$cmd_name}; $src = "cmdline"; } } if ( !defined $val ) { foreach my $file_basename (@cfg_list) { my $file = "$GLOBAL_PATH_TO_SCRIPT_DIR/$file_basename"; my $hash = LoadProperties($file) if ( -f $file ); if ( $hash && exists $hash->{$cfg_name} ) { $val = $hash->{$cfg_name}; $src = $file_basename; last; } } } if ( !defined $val ) { if ($default_sub) { $val = &$default_sub($cfg_name); $src = "default"; } } if ( defined $val ) { if ( ref($val) eq "HASH" ) { foreach my $k ( keys %{$val} ) { $CFG{$cfg_name}{$k} = ${$val}{$k}; printf( " %-35s: %-17s : %s\n", $cfg_name, $cmd_hash ? $src : "detected", $k . " => " . ${$val}{$k} ); } } else { $CFG{$cfg_name} = $val; if (ref($val) eq 'ARRAY') { printf( " %-35s: %-17s : %s\n", $cfg_name, $cmd_hash ? $src : "detected", join(' ', @$val) ); } else { printf( " %-35s: %-17s : %s\n", $cfg_name, $cmd_hash ? $src : "detected", $val ); } } } } sub InitGlobalBuildVars() { { my $destination_name_func = sub { return "$CFG{BUILD_OS}-$CFG{BUILD_RELEASE}-$CFG{BUILD_RELEASE_NO_SHORT}-$CFG{BUILD_TS}-$CFG{BUILD_TYPE}-$CFG{BUILD_NO}"; }; my $build_dir_func = sub { return "$CFG{BUILD_SOURCES_BASE_DIR}/.staging/$CFG{DESTINATION_NAME}"; }; my %cmd_hash = (); my @cmd_args = ( { name => "BUILD_NO", type => "=i", hash_src => \%cmd_hash, default_sub => sub { return GetNewBuildNo(); }, }, { name => "BUILD_TS", type => "=i", hash_src => \%cmd_hash, default_sub => sub { return GetNewBuildTs(); }, }, { name => "BUILD_OS", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return GetBuildOS(); }, }, { name => "BUILD_DESTINATION_BASE_DIR", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return "$GLOBAL_PATH_TO_TOP/BUILDS"; }, }, { name => "BUILD_SOURCES_BASE_DIR", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return $GLOBAL_PATH_TO_TOP; }, }, { name => "BUILD_RELEASE", type => "=s", hash_src => \%cmd_hash, default_sub => sub { Die("@_ not specified"); }, }, { name => "BUILD_RELEASE_NO", type => "=s", hash_src => \%cmd_hash, default_sub => sub { Die("@_ not specified"); }, }, { name => "BUILD_RELEASE_CANDIDATE", type => "=s", hash_src => \%cmd_hash, default_sub => sub { Die("@_ not specified"); }, }, { name => "BUILD_REVISION", type => "=s", hash_src => \%cmd_hash, default_sub => sub { "1"; }, }, { name => "BUILD_TYPE", type => "=s", hash_src => \%cmd_hash, default_sub => sub { Die("@_ not specified"); }, }, { name => "BUILD_THIRDPARTY_SERVER", type => "=s", hash_src => \%cmd_hash, default_sub => sub { Die("@_ not specified"); }, }, { name => "BUILD_PROD_FLAG", type => "!", hash_src => \%cmd_hash, default_sub => sub { return 1; }, }, { name => "BUILD_DEBUG_FLAG", type => "!", hash_src => \%cmd_hash, default_sub => sub { return 0; }, }, { name => "BUILD_DEV_TOOL_BASE_DIR", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return "$ENV{HOME}/.zm-dev-tools"; }, }, { name => "INTERACTIVE", type => "!", hash_src => \%cmd_hash, default_sub => sub { return 1; }, }, { name => "DISABLE_TAR", type => "!", hash_src => \%cmd_hash, default_sub => sub { return 0; }, }, { name => "DISABLE_BUNDLE", type => "!", hash_src => \%cmd_hash, default_sub => sub { return 0; }, }, { name => "EXCLUDE_GIT_REPOS", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return ""; }, }, { name => "GIT_OVERRIDES", type => "=s%", hash_src => \%cmd_hash, default_sub => sub { return {}; }, }, { name => "GIT_DEFAULT_TAG", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return undef; }, }, { name => "GIT_DEFAULT_REMOTE", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return undef; }, }, { name => "GIT_DEFAULT_BRANCH", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return undef; }, }, { name => "GIT_DEFAULT_REPO_NAME_SUFFIX", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return undef; }, }, { name => "STOP_AFTER_CHECKOUT", type => "!", hash_src => \%cmd_hash, default_sub => sub { return 0; }, }, { name => "ANT_OPTIONS", type => "=s@", hash_src => \%cmd_hash, default_sub => sub { return undef; }, }, { name => "MVN_OPTIONS", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return undef; }, }, { name => "BUILD_HOSTNAME", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return Net::Domain::hostfqdn; }, }, { name => "BUILD_ARCH", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return GetBuildArch(); }, }, { name => "PKG_OS_TAG", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return GetPkgOsTag(); }, }, { name => "BUILD_REVISION_NORMALIZED", type => "=s", hash_src => \%cmd_hash, default_sub => sub { NormalizeBuildRevision($CFG{BUILD_REVISION}) }, }, { name => "BUILD_RELEASE_NO_SHORT", type => "=s", hash_src => \%cmd_hash, default_sub => sub { my $x = $CFG{BUILD_RELEASE_NO}; $x =~ s/[.]//g; return $x; }, }, { name => "DESTINATION_NAME", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return &$destination_name_func; }, }, { name => "BUILD_DIR", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return &$build_dir_func; }, }, { name => "DEPLOY_URL_PREFIX", type => "=s", hash_src => \%cmd_hash, default_sub => sub { $CFG{LOCAL_DEPLOY} = 1; return "http://" . Net::Domain::hostfqdn . ":8008/$CFG{DESTINATION_NAME}"; }, }, { name => "DUMP_CONFIG_TO", type => "=s", hash_src => \%cmd_hash, default_sub => sub { return undef; }, }, ); { my @cmd_opts = map { $_->{opt} =~ y/A-Z_/a-z-/; $_; } # convert the opt named to lowercase to make command line options map { { opt => $_->{name}, opt_s => $_->{type} } } # create a new hash with keys opt, opt_s grep { $_->{type} } # get only names which have a valid type @cmd_args; my $help_func = sub { print "Usage: $0 \n"; print "Supported options: \n"; print " --" . "$_->{opt}$_->{opt_s}\n" foreach (@cmd_opts); exit(0); }; if ( !GetOptions( \%cmd_hash, ( map { $_->{opt} . $_->{opt_s} } @cmd_opts ), help => $help_func ) ) { print Die("wrong commandline options, use --help"); } } print "=========================================================================================================\n"; LoadConfiguration($_) foreach (@cmd_args); print "=========================================================================================================\n"; Die( "Bad version '$CFG{BUILD_RELEASE_NO}'", "$@" ) if ( $CFG{BUILD_RELEASE_NO} !~ m/^\d+[.]\d+[.]\d+$/ ); } foreach my $x (`grep -o '\\<[E][N][V]_[A-Z_]*\\>' '$GLOBAL_PATH_TO_SCRIPT_FILE' | sort | uniq`) { chomp($x); my $fmt2v = " %-35s: %s\n"; printf( $fmt2v, $x, defined $ENV{$x} ? $ENV{$x} : "(undef)" ); } print "=========================================================================================================\n"; { $ENV{PATH} = join( ":", "$CFG{BUILD_DEV_TOOL_BASE_DIR}/bin/Sencha/Cmd/4.0.2.67", #remove nw specific requirements reverse sort glob("$CFG{BUILD_DEV_TOOL_BASE_DIR}/*/bin"), "$CFG{BUILD_DEV_TOOL_BASE_DIR}/bin", "$ENV{PATH}" ); my $cc = DetectPrerequisite("cc"); my $cpp = DetectPrerequisite("c++"); my $java = DetectPrerequisite( "java", $ENV{JAVA_HOME} ? "$ENV{JAVA_HOME}/bin" : "" ); my $javac = DetectPrerequisite( "javac", $ENV{JAVA_HOME} ? "$ENV{JAVA_HOME}/bin" : "" ); my $mvn = DetectPrerequisite("mvn"); my $ant = DetectPrerequisite("ant"); my $ruby = DetectPrerequisite("ruby"); my $make = DetectPrerequisite("make"); $ENV{JAVA_HOME} ||= dirname( dirname( Cwd::realpath($javac) ) ); $ENV{PATH} = "$ENV{JAVA_HOME}/bin:$ENV{PATH}"; my $fmt2v = " %-35s: %s\n"; printf( $fmt2v, "USING javac", "$javac (JAVA_HOME=$ENV{JAVA_HOME})" ); printf( $fmt2v, "USING java", $java ); printf( $fmt2v, "USING maven", $mvn ); printf( $fmt2v, "USING ant", $ant ); printf( $fmt2v, "USING cc", $cc ); printf( $fmt2v, "USING c++", $cpp ); printf( $fmt2v, "USING ruby", $ruby ); printf( $fmt2v, "USING make", $make ); } print "=========================================================================================================\n"; if ( $CFG{DUMP_CONFIG_TO} ) { open( my $fh, ">", $CFG{DUMP_CONFIG_TO} ) or Die("Could not open '$CFG{DUMP_CONFIG_TO}'"); print $fh "# Dumping config to file...\n\n"; foreach my $k ( sort keys %CFG ) { my $v = $CFG{$k}; if ( ref($v) eq "HASH" ) { foreach my $sk ( sort keys %$v ) { printf $fh "%-30s = %s\n", '%' . $k, "$sk=$v->{$sk}"; } } else { printf $fh "%-30s = %s\n", $k, $v; } } print "NOTE: DUMPED CONFIG TO FILE - $CFG{DUMP_CONFIG_TO}\n"; } print "NOTE: THIS WILL STOP AFTER CHECKOUTS\n" if ( $CFG{STOP_AFTER_CHECKOUT} ); if ( $CFG{INTERACTIVE} ) { print "Press enter to proceed"; read STDIN, $_, 1; } } sub TranslateToPackagePath { my $deploy_pkg_into = shift; if ( my $pkg_dir = $deploy_pkg_into ) { $pkg_dir = "zimbra-" . lc( $CFG{BUILD_TYPE} ) if ( $pkg_dir eq "bundle" && $CFG{DISABLE_BUNDLE} ); $pkg_dir .= "-$ENV{ENV_ARCHIVE_SUFFIX_STR}" if ( $pkg_dir ne "bundle" && $ENV{ENV_ARCHIVE_SUFFIX_STR} ); return "$CFG{BUILD_DIR}/zm-packages/$pkg_dir/$CFG{PKG_OS_TAG}"; } else { return undef; } } sub Prepare() { RemoveTargetInDir( ".zcs-deps", $ENV{HOME} ) if ( $ENV{ENV_CACHE_CLEAR_FLAG} ); RemoveTargetInDir( ".ivy2/cache", $ENV{HOME} ) if ( $ENV{ENV_CACHE_CLEAR_FLAG} ); open( FD, ">", "$GLOBAL_PATH_TO_SCRIPT_DIR/.build.last_no_ts" ); print FD "BUILD_NO=$CFG{BUILD_NO}\n"; print FD "BUILD_TS=$CFG{BUILD_TS}\n"; close(FD); SysExec( "mkdir", "-p", "$CFG{BUILD_DIR}" ); SysExec( "mkdir", "-p", "$CFG{BUILD_DIR}/logs" ); SysExec( "mkdir", "-p", "$ENV{HOME}/.zcs-deps" ); SysExec( "mkdir", "-p", "$ENV{HOME}/.ivy2/cache" ); SysExec( "find", $CFG{BUILD_DIR}, "-type", "f", "-name", ".built.*", "-delete" ) if ( $ENV{ENV_CACHE_CLEAR_FLAG} ); my @TP_JARS = ( "https://files.zimbra.com/repository/ant-1.7.0-ziputil-patched/ant-1.7.0-ziputil-patched-1.0.jar", "https://files.zimbra.com/repository/ant-contrib/ant-contrib-1.0b1.jar", "https://files.zimbra.com/repository/jruby/jruby-complete-1.6.3.jar", "https://files.zimbra.com/repository/applet/plugin.jar", "https://files.zimbra.com/repository/servlet-api/servlet-api-3.1.jar", "https://files.zimbra.com/repository/unbound-ldapsdk/unboundid-ldapsdk-2.3.5-se.jar", ); for my $j_url (@TP_JARS) { if ( my $f = "$ENV{HOME}/.zcs-deps/" . basename($j_url) ) { if ( !-f $f ) { SysExec( "wget", $j_url, "-O", "$f.tmp" ); SysExec( "mv", "$f.tmp", $f ); } } } my ( $MAJOR, $MINOR, $MICRO ) = split( /[.]/, $CFG{BUILD_RELEASE_NO} ); EchoToFile( "$GLOBAL_PATH_TO_SCRIPT_DIR/RE/BUILD", $CFG{BUILD_NO} ); EchoToFile( "$GLOBAL_PATH_TO_SCRIPT_DIR/RE/MAJOR", $MAJOR ); EchoToFile( "$GLOBAL_PATH_TO_SCRIPT_DIR/RE/MINOR", $MINOR ); EchoToFile( "$GLOBAL_PATH_TO_SCRIPT_DIR/RE/MICRO", "${MICRO}_$CFG{BUILD_RELEASE_CANDIDATE}" ); close(FD); } sub EvalFile($;$) { my $fname = shift; my $file = "$GLOBAL_PATH_TO_SCRIPT_DIR/$fname"; Die( "Error in '$file'", "$@" ) if ( !-f $file ); my @ENTRIES; eval `cat '$file'`; Die( "Error in '$file'", "$@" ) if ($@); return \@ENTRIES; } sub LoadRepos() { my @agg_repos = (); my %exclusions = (); map { $exclusions{$_} = 1; } split(/,/, $CFG{EXCLUDE_GIT_REPOS}); push( @agg_repos, grep { !exists $exclusions{$_->{name}} } @{ EvalFile("instructions/$CFG{BUILD_TYPE}_repo_list.pl") } ); return \@agg_repos; } sub LoadRemotes() { my %details = @{ EvalFile("instructions/$CFG{BUILD_TYPE}_remote_list.pl") }; return \%details; } sub LoadBuilds($) { my $repo_list = shift; my @agg_builds = (); push( @agg_builds, @{ EvalFile("instructions/$CFG{BUILD_TYPE}_staging_list.pl") } ); my %repo_hash = map { $_->{name} => 1 } @$repo_list; my @filtered_builds = grep { my $d = $_->{dir}; $d =~ s/\/.*//; $repo_hash{$d} } # extract the repository from the 'dir' entry, filter out entries which do not exist in repo_list @agg_builds; return \@filtered_builds; } sub Checkout($) { my $repo_list = shift; print "\n"; print "=========================================================================================================\n"; print " Processing " . scalar(@$repo_list) . " repositories\n"; print "=========================================================================================================\n"; print "\n"; my $repo_remote_details = LoadRemotes(); for my $repo_details (@$repo_list) { Clone( $repo_details, $repo_remote_details ); } } sub RemoveTargetInDir($$) { my $target = shift; my $chdir = shift; s/\/\/*/\//g, s/\/*$// for ( my $sane_target = $target ); #remove multiple slashes, and ending slashes, dots if ( $sane_target && $chdir && -d $chdir ) { eval { RunInDir( cd => $chdir, child => sub { SysExec( "rm", "-rf", $sane_target ); } ); }; } } sub EmitArchiveAccessInstructions($) { my $archive_names = shift; if ( -f "/etc/redhat-release" ) { return < /etc/yum.repos.d/zimbra-packages.repo < /etc/apt/sources.list.d/zimbra-packages.list << EOM @{[ join("\n", map { "deb [trusted=yes] $CFG{DEPLOY_URL_PREFIX}/archives/$_/$CFG{PKG_OS_TAG} ./ # Zimbra Package Archive ($_)" } @$archive_names )]} EOM apt-get update EOM_SCRIPT EOM_DUMP } } sub Build($) { my $repo_list = shift; my @ALL_BUILDS = @{ LoadBuilds($repo_list) }; my $tool_attributes = { ant => [ "-Ddebug=$CFG{BUILD_DEBUG_FLAG}", "-Dis-production=$CFG{BUILD_PROD_FLAG}", "-Dzimbra.buildinfo.platform=$CFG{BUILD_OS}", "-Dzimbra.buildinfo.pkg_os_tag=$CFG{PKG_OS_TAG}", "-Dzimbra.buildinfo.version=$CFG{BUILD_RELEASE_NO}_$CFG{BUILD_RELEASE_CANDIDATE}_$CFG{BUILD_NO}", "-Dzimbra.buildinfo.revision=$CFG{BUILD_REVISION_NORMALIZED}", "-Dzimbra.buildinfo.type=$CFG{BUILD_TYPE}", "-Dzimbra.buildinfo.release=$CFG{BUILD_TS}", "-Dzimbra.buildinfo.date=$CFG{BUILD_TS}", "-Dzimbra.buildinfo.host=$CFG{BUILD_HOSTNAME}", "-Dzimbra.buildinfo.buildnum=$CFG{BUILD_NO}", ], make => [ "debug=$CFG{BUILD_DEBUG_FLAG}", "is-production=$CFG{BUILD_PROD_FLAG}", "zimbra.buildinfo.platform=$CFG{BUILD_OS}", "zimbra.buildinfo.pkg_os_tag=$CFG{PKG_OS_TAG}", "zimbra.buildinfo.version=$CFG{BUILD_RELEASE_NO}_$CFG{BUILD_RELEASE_CANDIDATE}_$CFG{BUILD_NO}", "zimbra.buildinfo.revision=$CFG{BUILD_REVISION_NORMALIZED}", "zimbra.buildinfo.type=$CFG{BUILD_TYPE}", "zimbra.buildinfo.release=$CFG{BUILD_TS}", "zimbra.buildinfo.date=$CFG{BUILD_TS}", "zimbra.buildinfo.host=$CFG{BUILD_HOSTNAME}", "zimbra.buildinfo.buildnum=$CFG{BUILD_NO}", ], mvn => [ ], }; push @{ $tool_attributes->{ant} }, ref $CFG{ANT_OPTIONS} eq 'ARRAY' ? @{ $CFG{ANT_OPTIONS} } : ($CFG{ANT_OPTIONS}) if defined $CFG{ANT_OPTIONS}; push( @{ $tool_attributes->{mvn} }, $CFG{MVN_OPTIONS} ) if ( $CFG{MVN_OPTIONS} ); my $cnt = 0; for my $build_info (@ALL_BUILDS) { ++$cnt; if ( my $dir = $build_info->{dir} ) { my $target_dir = "$CFG{BUILD_DIR}/$dir"; next unless ( !defined $ENV{ENV_BUILD_INCLUDE} || grep { $dir =~ /$_/ } split( ",", $ENV{ENV_BUILD_INCLUDE} ) ); RemoveTargetInDir( $dir, $CFG{BUILD_DIR} ) if ( ( $ENV{ENV_FORCE_REBUILD} && grep { $dir =~ /$_/ } split( ",", $ENV{ENV_FORCE_REBUILD} ) ) ); print "=========================================================================================================\n"; print color('blue') . "BUILDING: $dir ($cnt of " . scalar(@ALL_BUILDS) . ")" . color('reset') . "\n"; print "\n"; if ( $ENV{ENV_RESUME_FLAG} && -f "$target_dir/.built.$CFG{BUILD_TS}" ) { print color('yellow') . "SKIPPING... [TO REBUILD REMOVE '$target_dir']" . color('reset') . "\n"; print "=========================================================================================================\n"; print "\n"; } else { unlink glob "$target_dir/.built.*"; RunInDir( cd => $dir, child => sub { my $abs_dir = Cwd::abs_path(); if ( my $tool_seq = $build_info->{tool_seq} || [ "ant", "mvn", "make" ] ) { for my $tool (@$tool_seq) { if ( my $targets = $build_info->{ $tool . "_targets" } ) #Known values are: ant_targets, mvn_targets, make_targets { eval { SysExec( $tool, "clean" ) if ( !$ENV{ENV_SKIP_CLEAN_FLAG} ); }; SysExec( $tool, @{ $tool_attributes->{$tool} || [] }, @$targets ); } } } if ( my $stage_cmd = $build_info->{stage_cmd} ) { &$stage_cmd } if ( my $packages_path = TranslateToPackagePath( $build_info->{deploy_pkg_into} ) ) { SysExec( "mkdir", "-p", $packages_path ); SysExec( "rsync", "-av", "build/dist/$CFG{PKG_OS_TAG}/", "$packages_path/" ); } if ( !exists $build_info->{partial} ) { SysExec( "mkdir", "-p", "$target_dir" ); SysExec( "touch", "$target_dir/.built.$CFG{BUILD_TS}" ); } }, ); print "\n"; print "=========================================================================================================\n"; print "\n"; } } } RunInDir( cd => "$GLOBAL_PATH_TO_SCRIPT_DIR", child => sub { SysExec( "rsync", "-az", "--delete", ".", "$CFG{BUILD_DIR}/zm-build" ); SysExec( "mkdir", "-p", "$CFG{BUILD_DIR}/zm-build/$CFG{BUILD_ARCH}" ); my @ALL_PACKAGES = (); push( @ALL_PACKAGES, @{ EvalFile("instructions/$CFG{BUILD_TYPE}_package_list.pl") } ); push( @ALL_PACKAGES, "zcs-bundle" ) if ( !$CFG{DISABLE_TAR} ); for my $package_script (@ALL_PACKAGES) { if ( !defined $ENV{ENV_PACKAGE_INCLUDE} || grep { $package_script =~ /$_/ } split( ",", $ENV{ENV_PACKAGE_INCLUDE} ) ) { SysExec( " releaseNo='$CFG{BUILD_RELEASE_NO}' \\ releaseCandidate='$CFG{BUILD_RELEASE_CANDIDATE}' \\ branch='$CFG{BUILD_RELEASE}-$CFG{BUILD_RELEASE_NO_SHORT}' \\ buildNo='$CFG{BUILD_NO}' \\ os='$CFG{BUILD_OS}' \\ PKG_OS_TAG='$CFG{PKG_OS_TAG}' \\ buildType='$CFG{BUILD_TYPE}' \\ repoDir='$CFG{BUILD_DIR}' \\ arch='$CFG{BUILD_ARCH}' \\ buildTimeStamp='$CFG{BUILD_TS}' \\ buildLogFile='$CFG{BUILD_DIR}/logs/build.log' \\ zimbraThirdPartyServer='$CFG{BUILD_THIRDPARTY_SERVER}' \\ bash $GLOBAL_PATH_TO_SCRIPT_DIR/instructions/bundling-scripts/$package_script.sh " ); if ( $CFG{DISABLE_BUNDLE} ) # move created packages out of the tar for independent deployment in archive. { my $alt_dest_pkg_dir = TranslateToPackagePath("bundle"); SysExec( "mkdir", "-p", $alt_dest_pkg_dir ); SysExec( "rsync", "-av", "--remove-source-files", "$CFG{BUILD_DIR}/zm-build/$CFG{BUILD_ARCH}/", "$alt_dest_pkg_dir/" ); } } } }, ); } sub Deploy() { print "\n"; print "=========================================================================================================\n"; print color('blue') . "DEPLOYING ARTIFACTS" . color('reset') . "\n"; print "\n"; print "\n"; my $destination_dir = "$CFG{BUILD_DESTINATION_BASE_DIR}/$CFG{DESTINATION_NAME}"; SysExec( "mkdir", "-p", "$destination_dir/archives" ); my @archive_names = map { basename($_) } grep { -d $_ && $_ !~ m/\/bundle$/ } glob("$CFG{BUILD_DIR}/zm-packages/*"); foreach my $archive_name (@archive_names) { SysExec( "rsync", "-av", "--delete", "$CFG{BUILD_DIR}/zm-packages/$archive_name/", "$destination_dir/archives/$archive_name" ); if ( -f "/etc/redhat-release" ) { if ( !$CFG{LOCAL_DEPLOY} || DetectPrerequisite( "createrepo", "", 1 ) ) { SysExec("cd '$destination_dir/archives/$archive_name/$CFG{PKG_OS_TAG}' && createrepo '.'"); } } else { if ( !$CFG{LOCAL_DEPLOY} || DetectPrerequisite( "dpkg-scanpackages", "", 1 ) ) { SysExec("cd '$destination_dir/archives/$archive_name/$CFG{PKG_OS_TAG}' && dpkg-scanpackages '.' /dev/null > Packages"); } } } EchoToFile( "$destination_dir/archive-access-$CFG{PKG_OS_TAG}.txt", EmitArchiveAccessInstructions( \@archive_names ) ); SysExec("cp $CFG{BUILD_DIR}/zm-build/zcs-*.$CFG{BUILD_TS}.tgz $destination_dir/") if ( !$CFG{DISABLE_TAR} ); if ( $CFG{LOCAL_DEPLOY} ) { if ( !-f "/etc/nginx/conf.d/zimbra-pkg-archives-host.conf" || !`pgrep -f -P1 '[n]ginx'` ) { print "\n"; print "=========================================================================================================\n"; print </dev/null service nginx restart service nginx status EOM_SCRIPT @{[color('reset')]} EOM_DUMP } } print "\n"; print "=========================================================================================================\n"; print "\n"; } sub GetNewBuildNo() { my $line = 1000; my $file = "$GLOBAL_PATH_TO_SCRIPT_DIR/.build.number"; if ( -f $file ) { open( FD1, "<", $file ); $line = ; close(FD1); $line += 1; } open( FD2, ">", $file ); printf( FD2 "%s\n", $line ); close(FD2); return $line; } sub GetNewBuildTs() { chomp( my $x = `date +'%Y%m%d%H%M%S'` ); return $x; } sub GetBuildOS() # FIXME - use standard mechanism { our $detected_os = undef; sub detect_os { chomp( $detected_os = `$GLOBAL_PATH_TO_SCRIPT_DIR/rpmconf/Build/get_plat_tag.sh` ) if ( !$detected_os ); return $detected_os if ($detected_os); Die("Unknown OS"); } return detect_os(); } sub GetBuildArch() { my $b_os = $CFG{BUILD_OS}; return "amd64" if ( $b_os =~ /UBUNTU[0-9]+_64/ ); return "x86_64" if ( $b_os =~ /RHEL[0-9]+_64/ || $b_os =~ /CENTOS[0-9]+_64/ ); Die("Could not determine BUILD_ARCH"); } sub GetPkgOsTag() { my $b_os = $CFG{BUILD_OS}; return "u$1" if ( $b_os =~ /UBUNTU([0-9]+)_/ ); return "r$1" if ( $b_os =~ /RHEL([0-9]+)_/ || $b_os =~ /CENTOS([0-9]+)_/ ); Die("Could not determine PKG_OS_TAG"); } ############################################################################################## sub Clone($$) { my $repo_details = shift; my $repo_remote_details = shift; my $repo_name = $repo_details->{name}; my $repo_branch_csv = $CFG{GIT_OVERRIDES}->{"$repo_name.branch"} || $repo_details->{branch} || $CFG{GIT_DEFAULT_BRANCH} || "develop"; my $repo_tag_csv = $CFG{GIT_OVERRIDES}->{"$repo_name.tag"} || $repo_details->{tag} || $CFG{GIT_DEFAULT_TAG} if ( $CFG{GIT_OVERRIDES}->{"$repo_name.tag"} || !$CFG{GIT_OVERRIDES}->{"$repo_name.branch"} ); my $repo_remote = $CFG{GIT_OVERRIDES}->{"$repo_name.remote"} || $repo_details->{remote} || $CFG{GIT_DEFAULT_REMOTE} || "gh-zm"; my $repo_url_prefix = $CFG{GIT_OVERRIDES}->{"$repo_remote.url-prefix"} || $repo_remote_details->{$repo_remote}->{'url-prefix'} || Die( "unresolved url-prefix for remote='$repo_remote'", "" ); my $repo_name_suffix = $CFG{GIT_OVERRIDES}->{"$repo_name.repo_name_suffix"} || $repo_details->{repo_name_suffix} || $CFG{GIT_DEFAULT_REPO_NAME_SUFFIX}; $repo_url_prefix =~ s,/*$,,; my $repo_dir = "$CFG{BUILD_SOURCES_BASE_DIR}/$repo_name"; my $repo_source = $repo_url_prefix . "/" . ($repo_name_suffix ? "$repo_name$repo_name_suffix.git" : "$repo_name.git"); if ( !-d $repo_dir ) { my $s = 0; foreach my $minus_b_arg ( split( /,/, $repo_tag_csv ? $repo_tag_csv : $repo_branch_csv ) ) { my $r = SysExec("git", "ls-remote", $repo_tag_csv ? "--tags" : "--heads", $repo_source, "$minus_b_arg"); if ( $r->{success} && "@{$r->{out}}" =~ /$minus_b_arg$/ ) { my @clone_cmd_args = ( "git", "clone" ); push( @clone_cmd_args, "--depth=1" ) if ( not $ENV{ENV_GIT_FULL_CLONE} and $repo_name ne "zm-mailbox"); push( @clone_cmd_args, "-b", $minus_b_arg ); push( @clone_cmd_args, $repo_source, "$repo_dir"); print "\n"; my $r = SysExec(@clone_cmd_args); if ( $r->{success} ) { $s++; last; } } } Die("Clone Attempts Failed") if ( !$s ); RemoveTargetInDir( $repo_name, $CFG{BUILD_DIR} ); } else { if ( !defined $ENV{ENV_GIT_UPDATE_INCLUDE} || grep { $repo_name =~ /$_/ } split( ",", $ENV{ENV_GIT_UPDATE_INCLUDE} ) ) { if ($repo_tag_csv) { RunInDir( cd => $repo_dir, child => sub { my $s = 0; foreach my $minus_b_arg ( split( /,/, $repo_tag_csv ) ) { print "\n"; my $r = SysExec( "git", "checkout", $minus_b_arg ); if ( $r->{success} ) { $s++; last; } } Die("Clone Attempts Failed") if ( !$s ); }, ); RemoveTargetInDir( $repo_name, $CFG{BUILD_DIR} ); } else { print "\n"; RunInDir( cd => $repo_dir, child => sub { my $z = SysExec( "git", "pull", "--ff-only" ); if ( "@{$z->{out}}" !~ /Already up-to-date/ ) { RemoveTargetInDir( $repo_name, $CFG{BUILD_DIR} ); } }, ); } } } } sub SysExec(@) { my $options = shift if ( @_ && ref( $_[0] ) eq "HASH" ); $options->{continue_on_error} ||= 0; $options->{verbose} ||= 1; my $cmd_str = "@_"; if ( $options->{verbose} ) { print color('green') . "#: pwd=@{[Cwd::getcwd()]}" . color('reset') . "\n"; print color('green') . "#: $cmd_str" . color('reset') . "\n"; } $! = 0; my ( $success, $error_message, $full_buf, $stdout_buf, $stderr_buf ) = run( command => \@_, verbose => 1 ); Die( "cmd='$cmd_str'", $error_message ) if ( !$success && !$options->{continue_on_error} ); return { msg => $error_message, out => $stdout_buf, err => $stderr_buf, success => $success }; } sub LoadProperties($) { my $f = shift; my $x = SlurpFile($f); my @cfg_kvs = map { $_ =~ s/^\s+|\s+$//g; $_ } # trim map { split( /=/, $_, 2 ) } # split around = map { $_ =~ s/#.*$//g; $_ } # strip comments grep { $_ !~ /^\s*#/ } # ignore comments grep { $_ !~ /^\s*$/ } # ignore empty lines @$x; my %ret_hash = (); for ( my $e = 0 ; $e < scalar @cfg_kvs ; $e += 2 ) { my $probe_key = $cfg_kvs[$e]; my $probe_val = $cfg_kvs[ $e + 1 ]; if ( $probe_key =~ /^%(.*)/ ) { my @val_kv_pair = split( /=/, $probe_val, 2 ); $ret_hash{$1}{ $val_kv_pair[0] } = $val_kv_pair[1]; } else { $ret_hash{$probe_key} = $probe_val; } } return \%ret_hash; } sub SlurpFile($) { my $f = shift; open( FD, "<", "$f" ) || Die( "In open for read", "file='$f'" ); chomp( my @x = ); close(FD); return \@x; } sub EchoToFile($$) { my $f = shift; my $w = shift; open( FD, ">", "$f" ) || Die( "In open for write", "file='$f'" ); print FD $w . "\n"; close(FD); } sub DetectPrerequisite($;$$) { my $util_name = shift; my $additional_path = shift || ""; my $warn_only = shift || 0; chomp( my $detected_util = `PATH="$additional_path:\$PATH" \\which "$util_name" 2>/dev/null | sed -e 's,//*,/,g'` ); return $detected_util if ($detected_util); Die( "Prerequisite '$util_name' missing in PATH" . "\nTry: " . "\n [ -f /etc/redhat-release ] && sudo yum install perl-Data-Dumper perl-IPC-Cmd gcc-c++ java-1.8.0-openjdk ant ant-junit ruby maven wget rpm-build createrepo" . "\n [ -f /etc/redhat-release ] || sudo apt-get install software-properties-common openjdk-8-jdk ant ant-optional ruby git maven build-essential", "", $warn_only ); } sub RunInDir(%) { my %args = (@_); my $chdir = $args{cd}; my $child = $args{child}; my $child_pid = fork(); Die("FAILURE while forking") if ( !defined $child_pid ); if ( $child_pid != 0 ) # parent { while ( waitpid( $child_pid, 0 ) == -1 ) { } Die( "child $child_pid died", einfo($?) ) if ( $? != 0 ); } else { Die( "chdir to '$chdir' failed", einfo($?) ) if ( $chdir && !chdir($chdir) ); $! = 0; &$child; exit(0); } } sub einfo() { my @SIG_NAME = split( / /, $Config{sig_name} ); return "ret=" . ( $? >> 8 ) . ( ( $? & 127 ) ? ", sig=SIG" . $SIG_NAME[ $? & 127 ] : "" ); } sub Die($;$$) { my $msg = shift; my $info = shift || ""; my $warn_only = shift || 0; my $err = "$!"; print "\n" if ( !$warn_only ); print "\n"; print "=========================================================================================================\n"; print color('red') . "FAILURE MSG" . color('reset') . " : $msg\n" if ( !$warn_only ); print color('red') . "WARNING MSG" . color('reset') . " : $msg\n" if ($warn_only); print color('red') . "SYSTEM ERR " . color('reset') . " : $err\n" if ($err); print color('red') . "EXTRA INFO " . color('reset') . " : $info\n" if ($info); print "\n"; print "=========================================================================================================\n"; if ( !$warn_only ) { print color('red'); print "--Stack Trace-- ($$)\n"; my $i = 1; while ( ( my @call_details = ( caller( $i++ ) ) ) ) { print $call_details[1] . ":" . $call_details[2] . " called from " . $call_details[3] . "\n"; } print color('reset'); print "\n"; print "=========================================================================================================\n"; die "END" } } sub NormalizeBuildRevision { my ($val) = @_; return $val unless defined $val; if ($CFG{PKG_OS_TAG} =~ /^r/) { return $val if $val =~ /^[\w]+$/; $val =~ s/[~-]/_/g; $val =~ s/_+/_/g; $val =~ s/^_//; $val =~ s/_$//; } return $val; } ############################################################################################## sub main() { InitGlobalBuildVars(); my $all_repos = LoadRepos(); Prepare(); Checkout($all_repos); if ( !$CFG{STOP_AFTER_CHECKOUT} ) { Build($all_repos); Deploy(); } } main(); ############################################################################################## ================================================ FILE: config.build.in ================================================ # Example config: # - please change as appropriate. # - command line overrides the config. BUILD_RELEASE = JUDASPRIEST BUILD_RELEASE_NO = 8.8.0 BUILD_RELEASE_CANDIDATE = GA BUILD_TYPE = FOSS BUILD_THIRDPARTY_SERVER = zdev-vm008.eng.zimbra.com # Example of GIT_OVERRIDES (hash) # %GIT_OVERRIDES = myremote.url-prefix=ssh://git@stash.corp.synacor.com:7999/~user/zm-mailbox.git # %GIT_OVERRIDES = zm-mailbox.branch=dev # %GIT_OVERRIDES = zm-mailbox.remote=myremote # %GIT_OVERRIDES = zm-mailbox.tag=judaspriest-872 # .tag always overrides .branch ================================================ FILE: instructions/.gitignore ================================================ NETWORK_*.pl ================================================ FILE: instructions/FOSS_package_list.pl ================================================ @ENTRIES = ( "zimbra-core", "zimbra-ldap", "zimbra-logger", "zimbra-mta", "zimbra-dnscache", "zimbra-snmp", "zimbra-store", "zimbra-apache", "zimbra-spell", "zimbra-proxy", "zimbra-imapd", ); ================================================ FILE: instructions/FOSS_remote_list.pl ================================================ @ENTRIES = ( "gh-zm" => { 'url-prefix' => "https://github.com/Zimbra", }, "gh-ks" => { 'url-prefix' => "https://github.com/kohlschutter", }, ); ================================================ FILE: instructions/FOSS_repo_list.pl ================================================ @ENTRIES = ( { name => "ant-1.7.0-ziputil-patched", }, { name => "ant-tar-patched", }, { name => "ical4j-0.9.16-patched", }, { name => "junixsocket", tag => "junixsocket-parent-2.0.4", remote => "gh-ks",}, { name => "nekohtml-1.9.13", }, { name => "java-html-sanitizer-release-20190610.1",}, { name => "antisamy", }, { name => "zm-admin-console", }, { name => "zm-admin-help-common", }, { name => "zm-ajax", }, { name => "zm-admin-ajax", }, { name => "zm-amavis", }, { name => "zm-aspell", }, { name => "zm-bulkprovision-admin-zimlet", }, { name => "zm-bulkprovision-store", }, { name => "zm-certificate-manager-admin-zimlet", }, { name => "zm-certificate-manager-store", }, { name => "zm-charset", }, { name => "zm-clam-scanner-store", }, { name => "zm-core-utils", }, { name => "zm-db-conf", }, { name => "zm-dnscache", }, { name => "zm-downloads", }, { name => "zm-freshclam", }, { name => "zm-helptooltip-zimlet", }, { name => "zm-jetty-conf", }, { name => "zm-jython", }, { name => "zm-launcher", }, { name => "zm-ldap-utilities", }, { name => "zm-ldap-utils-store", }, { name => "zm-licenses", }, { name => "zm-mailbox", }, { name => "zm-migration-tools", }, { name => "zm-mta", }, { name => "zm-nginx-conf", }, { name => "zm-nginx-lookup-store", }, { name => "zm-openid-consumer-store", }, { name => "zm-pkg-tool", }, { name => "zm-postfix", }, { name => "zm-proxy-config-admin-zimlet", }, { name => "zm-ssdb-ephemeral-store", }, { name => "zm-taglib", }, # zm-timezones repo can be removed and made independent of zm-zextras # zm-timezones cannot be done unless the packages from it are pushed to public repo # zm-timezones is already excluded in CircleCI builds via --exclude-git-repo=... { name => "zm-timezones", }, { name => "zm-versioncheck-admin-zimlet", }, { name => "zm-versioncheck-store", }, { name => "zm-versioncheck-utilities", }, { name => "zm-viewmail-admin-zimlet", }, { name => "zm-web-client", }, { name => "zm-webclient-portal-example", }, { name => "zm-zcs", }, { name => "zm-zcs-lib", }, { name => "zm-zimlets", }, { name => "zm-oauth-social", }, { name => "zm-gql", }, ); ================================================ FILE: instructions/FOSS_staging_list.pl ================================================ @ENTRIES = ( { "dir" => "zm-mailbox", "ant_targets" => ["pkg-after-plough-through-tests"], "deploy_pkg_into" => "bundle", "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-mailbox/store-conf/"); SysExec("rsync -az store-conf/conf $CFG{BUILD_DIR}/zm-mailbox/store-conf/"); SysExec("install -T -D store/build/dist/versions-init.sql $CFG{BUILD_DIR}/zm-mailbox/store/build/dist/versions-init.sql"); }, }, { "dir" => "zm-mailbox/store", "ant_targets" => ["publish-store-test", "test", "coverage", "sonar-scan"], "stage_cmd" => undef, }, { # This repo can be removed and made independent of zm-zextras # This cannot be done unless the packages from zm-timezones are pushed to public repo # This is already excluded in CircleCI builds "dir" => "zm-timezones", "ant_targets" => ["pkg", "sonar-scan"], "deploy_pkg_into" => "bundle", }, { "dir" => "junixsocket/junixsocket-native", "mvn_targets" => ["package"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/junixsocket/junixsocket-native/build"); SysExec("cp -f target/nar/junixsocket-native-*/lib/*/jni/libjunixsocket-native-*.so $CFG{BUILD_DIR}/junixsocket/junixsocket-native/build/"); SysExec("cp -f target/junixsocket-native-*.nar $CFG{BUILD_DIR}/junixsocket/junixsocket-native/build/"); }, }, { "dir" => "zm-taglib", "ant_targets" => ["publish-local", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-taglib/build"); SysExec("cp -f build/zm-taglib*.jar $CFG{BUILD_DIR}/zm-taglib/build/"); }, }, { "dir" => "zm-charset", "ant_targets" => ["publish-local", "sonar-scan"], "stage_cmd" => undef, }, { "dir" => "zm-ldap-utilities", "ant_targets" => ["build-dist"], "stage_cmd" => sub { SysExec("(cd .. && rsync -az --relative zm-ldap-utilities/build/dist $CFG{BUILD_DIR}/)"); SysExec("(cd .. && rsync -az --relative zm-ldap-utilities/src/ldap/migration $CFG{BUILD_DIR}/)"); SysExec("(cd .. && rsync -az --relative zm-ldap-utilities/conf $CFG{BUILD_DIR}/)"); SysExec("(cd .. && rsync -az --relative zm-ldap-utilities/src/libexec $CFG{BUILD_DIR}/)"); }, }, { "dir" => "zm-ajax", "ant_targets" => ["publish-local", "sonar-scan"], "stage_cmd" => undef, }, { "dir" => "zm-admin-ajax", "ant_targets" => ["publish-local", "sonar-scan"], "stage_cmd" => undef, }, { "dir" => "zm-ssdb-ephemeral-store", "ant_targets" => ["publish-local", "test", "coverage", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-ssdb-ephemeral-store/build/dist"); SysExec("cp -f build/zm-ssdb-ephemeral-store*.jar $CFG{BUILD_DIR}/zm-ssdb-ephemeral-store/build/dist"); }, }, { "dir" => "zm-openid-consumer-store", "ant_targets" => ["dist-package", "test", "coverage", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-openid-consumer-store/build/dist"); SysExec("cp -f -r build/dist $CFG{BUILD_DIR}/zm-openid-consumer-store/build/"); }, }, { "dir" => "zm-clam-scanner-store", "ant_targets" => ["publish-local", "test", "coverage", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-clam-scanner-store/build/dist"); SysExec("cp -f -rp build/zm-clam-scanner-store-*.jar $CFG{BUILD_DIR}/zm-clam-scanner-store/build/dist"); }, }, { "dir" => "zm-licenses", "ant_targets" => undef, "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-licenses"); SysExec("(cd .. && rsync -az --relative zm-licenses/ $CFG{BUILD_DIR}/)"); }, }, { "dir" => "zm-nginx-lookup-store", "ant_targets" => ["publish-local", "test", "coverage", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-nginx-lookup-store/build/dist"); SysExec("cp -f -rp build/zm-nginx-lookup-store-*.jar $CFG{BUILD_DIR}/zm-nginx-lookup-store/build/dist"); }, }, { "dir" => "zm-versioncheck-admin-zimlet", "ant_targets" => ["package-zimlet"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-versioncheck-admin-zimlet/build/zimlet"); SysExec("cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-versioncheck-admin-zimlet/build/zimlet"); }, }, { "dir" => "zm-bulkprovision-admin-zimlet", "ant_targets" => ["package-zimlet"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-bulkprovision-admin-zimlet/build/zimlet"); SysExec("cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-bulkprovision-admin-zimlet/build/zimlet"); }, }, { "dir" => "zm-certificate-manager-admin-zimlet", "ant_targets" => ["package-zimlet"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-certificate-manager-admin-zimlet/build/zimlet"); SysExec("cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-certificate-manager-admin-zimlet/build/zimlet"); }, }, { "dir" => "zm-proxy-config-admin-zimlet", "ant_targets" => ["package-zimlet"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-proxy-config-admin-zimlet/build/zimlet"); SysExec("cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-proxy-config-admin-zimlet/build/zimlet"); }, }, { "dir" => "zm-helptooltip-zimlet", "ant_targets" => ["package-zimlet"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-helptooltip-zimlet/build/zimlet"); SysExec("cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-helptooltip-zimlet/build/zimlet"); }, }, { "dir" => "zm-viewmail-admin-zimlet", "ant_targets" => ["package-zimlet"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-viewmail-admin-zimlet/build/zimlet"); SysExec("cp -f build/zimlet/*.zip $CFG{BUILD_DIR}/zm-viewmail-admin-zimlet/build/zimlet"); }, }, { "dir" => "zm-zimlets", "ant_targets" => [ "package-zimlets", "jar", "sonar-scan" ], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-zimlets/conf"); SysExec("cp -f conf/zimbra.tld $CFG{BUILD_DIR}/zm-zimlets/conf"); SysExec("cp -f conf/web.xml.production $CFG{BUILD_DIR}/zm-zimlets/conf"); SysExec("mkdir -p $CFG{BUILD_DIR}/zm-zimlets/build/dist/zimlets"); SysExec("cp -f build/dist/zimlets/*.zip $CFG{BUILD_DIR}/zm-zimlets/build/dist/zimlets"); SysExec("mkdir -p $CFG{BUILD_DIR}/zm-zimlets/build/dist"); SysExec("cp -f build/dist/lib/zimlettaglib.jar $CFG{BUILD_DIR}/zm-zimlets/build/dist/zimlettaglib.jar"); }, }, { "dir" => "zm-web-client", "ant_targets" => ["pkg"], "deploy_pkg_into" => "bundle", }, { "dir" => "zm-admin-help-common", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-admin-help-common $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-versioncheck-utilities", "ant_targets" => undef, "stage_cmd" => sub { SysExec("(cd .. && rsync -az --relative zm-versioncheck-utilities/src/libexec/zmcheckversion $CFG{BUILD_DIR}/)"); }, }, { "dir" => "zm-webclient-portal-example", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-webclient-portal-example $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-downloads", "ant_targets" => undef, "stage_cmd" => sub { SysExec("(cd .. && rsync -az --relative --exclude '.git' zm-downloads $CFG{BUILD_DIR}/)"); }, }, { "dir" => "zm-db-conf", "ant_targets" => undef, "stage_cmd" => sub { SysExec("(cd .. && rsync -az --relative zm-db-conf/src/db/migration $CFG{BUILD_DIR}/)"); SysExec("(cd .. && rsync -az --relative zm-db-conf/src/db/mysql $CFG{BUILD_DIR}/)"); }, }, { "dir" => "zm-admin-console", "ant_targets" => ["pkg"], "deploy_pkg_into" => "bundle", }, { "dir" => "zm-aspell", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-aspell $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-dnscache", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-dnscache $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-amavis", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-amavis $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-nginx-conf", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-nginx-conf $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-postfix", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-postfix $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-core-utils", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-core-utils $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-migration-tools", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-migration-tools $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-bulkprovision-store", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-bulkprovision-store"); SysExec("cp -f -r ../zm-bulkprovision-store/build $CFG{BUILD_DIR}/zm-bulkprovision-store"); }, }, { "dir" => "zm-certificate-manager-store", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-certificate-manager-store"); SysExec("cp -f -r ../zm-certificate-manager-store/build $CFG{BUILD_DIR}/zm-certificate-manager-store"); }, }, { "dir" => "zm-versioncheck-store", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-versioncheck-store"); SysExec("cp -f -r ../zm-versioncheck-store/build $CFG{BUILD_DIR}/zm-versioncheck-store"); }, }, { "dir" => "zm-ldap-utils-store", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-ldap-utils-store"); SysExec("cp -f -r ../zm-ldap-utils-store/build $CFG{BUILD_DIR}/zm-ldap-utils-store"); }, }, { "dir" => "ant-1.7.0-ziputil-patched", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => undef, }, { "dir" => "ant-tar-patched", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => undef, }, { "dir" => "nekohtml-1.9.13", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => undef, }, { "dir" => "java-html-sanitizer-release-20190610.1", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => undef, }, { "dir" => "antisamy", "ant_targets" => ["jar", "sonar-scan"], "stage_cmd" => undef, }, { "dir" => "ical4j-0.9.16-patched", "ant_targets" => [ "clean-compile", "package", "sonar-scan" ], "stage_cmd" => undef, }, { "dir" => "zm-zcs-lib", "ant_targets" => ["dist", "pkg"], "stage_cmd" => sub { SysExec("(cd .. && rsync -az --relative zm-zcs-lib $CFG{BUILD_DIR}/)"); }, "deploy_pkg_into" => "bundle", }, { "dir" => "zm-jython", "ant_targets" => undef, "stage_cmd" => sub { SysExec("(cd .. && rsync -az --relative zm-jython $CFG{BUILD_DIR}/)"); }, }, { "dir" => "zm-mta", "ant_targets" => undef, "stage_cmd" => sub { SysExec("(cd .. && rsync -az --relative zm-mta $CFG{BUILD_DIR}/)"); }, }, { "dir" => "zm-freshclam", "ant_targets" => undef, "stage_cmd" => sub { SysExec("(cd .. && rsync -az --relative zm-freshclam $CFG{BUILD_DIR}/)"); }, }, { "dir" => "zm-launcher", "make_targets" => ["JAVA_BINARY=/opt/zimbra/common/bin/java"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-launcher/build/dist"); SysExec("cp -f build/zmmailboxd* $CFG{BUILD_DIR}/zm-launcher/build/dist"); }, }, { "dir" => "zm-jetty-conf", "ant_targets" => undef, "stage_cmd" => sub { SysExec("cp -f -r ../zm-jetty-conf $CFG{BUILD_DIR}"); }, }, { "dir" => "zm-oauth-social", "ant_targets" => ["publish-local", "oauth-social-common-jar", "oauth-social-jar", "test", "coverage", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-oauth-social/build/dist"); SysExec("cp -f -rp build/zm-oauth-social*.jar $CFG{BUILD_DIR}/zm-oauth-social/build/dist"); }, }, { "dir" => "zm-gql", "ant_targets" => ["publish-local", "test", "coverage", "sonar-scan"], "stage_cmd" => sub { SysExec("mkdir -p $CFG{BUILD_DIR}/zm-gql/build/dist"); SysExec("cp -f -rp build/zm-gql-*.jar $CFG{BUILD_DIR}/zm-gql/build/dist"); }, }, ); ================================================ FILE: instructions/bundling-scripts/.gitignore ================================================ zimbra-archiving.sh zimbra-convertd.sh ================================================ FILE: instructions/bundling-scripts/utils.sh ================================================ #!/bin/bash Copy() { if [ $# -ne 2 ] then echo "Usage: Copy " 1>&2 exit 1; fi local src_file="$1"; shift; local dest_file="$1"; shift; mkdir -p "$(dirname "$dest_file")" cp -f "$src_file" "$dest_file" } Cpy2() { if [ $# -ne 2 ] then echo "Usage: Cpy2 " 1>&2 exit 1; fi local src_file="$1"; shift; local dest_dir="$1"; shift; mkdir -p "$dest_dir" cp -f "$src_file" "$dest_dir" } CreatePackage() { if [ $# -ne 1 ] then echo "Usage: CreatePackage " 1>&2 exit 1 fi if [[ $1 == UBUNTU* ]] then CreateDebianPackage elif [[ $1 == RHEL* ]] then CreateRhelPackage else echo "OS not supported. Run using UBUNTU or RHEL system. " exit 1 fi if [ $? -ne 0 ]; then echo -e "\t### ${currentPackage} package building failed ###" >> ${buildLogFile} else echo -e "\t*** ${currentPackage} package successfully created ***" >> ${buildLogFile} fi } ================================================ FILE: instructions/bundling-scripts/zcs-bundle.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** cd ${repoDir}/zm-build if [ "${buildType}" = "NETWORK" ] then ZCS_REL=zcs-${buildType}-${releaseNo}_${releaseCandidate}_${buildNo}.${os}.${buildTimeStamp} else ZCS_REL=zcs-${releaseNo}_${releaseCandidate}_${buildNo}.${os}.${buildTimeStamp} fi mkdir -p $ZCS_REL/bin mkdir -p $ZCS_REL/data mkdir -p $ZCS_REL/docs/en_US mkdir -p $ZCS_REL/lib/jars mkdir -p $ZCS_REL/packages mkdir -p $ZCS_REL/util/modules cp -f ${repoDir}/zm-build/RE/README.txt ${ZCS_REL}/ cp -f ${repoDir}/zm-build/rpmconf/Build/checkLicense.pl ${ZCS_REL}/bin cp -f ${repoDir}/zm-build/rpmconf/Build/checkService.pl ${ZCS_REL}/bin cp -f ${repoDir}/zm-build/rpmconf/Build/get_plat_tag.sh ${ZCS_REL}/bin cp -f ${repoDir}/zm-build/rpmconf/Build/zmValidateLdap.pl ${ZCS_REL}/bin cp -f ${repoDir}/zm-build/rpmconf/Install/Util/addUser.sh ${ZCS_REL}/util cp -f ${repoDir}/zm-build/rpmconf/Install/Util/globals.sh ${ZCS_REL}/util cp -f ${repoDir}/zm-build/rpmconf/Install/Util/modules/getconfig.sh ${ZCS_REL}/util/modules cp -f ${repoDir}/zm-build/rpmconf/Install/Util/modules/packages.sh ${ZCS_REL}/util/modules cp -f ${repoDir}/zm-build/rpmconf/Install/Util/modules/postinstall.sh ${ZCS_REL}/util/modules cp -f ${repoDir}/zm-build/rpmconf/Install/Util/utilfunc.sh ${ZCS_REL}/util cp -f ${repoDir}/zm-build/rpmconf/Install/install.sh ${ZCS_REL}/ cp -f ${repoDir}/zm-core-utils/src/libexec/zmdbintegrityreport ${ZCS_REL}/bin cp -f ${repoDir}/zm-mailbox/store/build/dist/versions-init.sql ${ZCS_REL}/data # all local packages to bundle cp -f ${repoDir}/zm-build/${arch}/*.* ${ZCS_REL}/packages for pkgf in ${repoDir}/zm-packages/bundle/*/*.{rpm,deb,changes} do if ! [[ "$pkgf" =~ src.rpm$ ]] then [ -f "$pkgf" ] && cp -f "$pkgf" ${ZCS_REL}/packages fi done if [ -f "/etc/redhat-release" ] then if \which createrepo 2>&- then ( cd ${ZCS_REL}/packages && createrepo . ) # Create index of packages fi else if \which dpkg-scanpackages 2>&- then ( cd ${ZCS_REL}/packages && dpkg-scanpackages . /dev/null > Packages ) # Create index of packages fi fi chmod 755 ${ZCS_REL}/bin/checkService.pl chmod 755 ${ZCS_REL}/bin/checkLicense.pl chmod 755 ${ZCS_REL}/bin/zmValidateLdap.pl chmod 755 ${ZCS_REL}/bin/zmdbintegrityreport chmod 755 ${ZCS_REL}/install.sh cp -f ${repoDir}/zm-admin-help-common/WebRoot/help/en_US/admin/pdf/*.pdf ${ZCS_REL}/docs/en_US cp -f ${repoDir}/zm-admin-help-common/WebRoot/help/en_US/admin/txt/readme_binary.txt ${ZCS_REL}/readme_binary_en_US.txt if [ "${buildType}" = "NETWORK" ] then cp -f ${repoDir}/zm-admin-help-network/WebRoot/help/en_US/admin/pdf/*.pdf ${ZCS_REL}/docs/en_US cp -f ${repoDir}/zm-admin-help-network/WebRoot/help/en_US/admin/txt/readme_binary.txt ${ZCS_REL}/readme_binary_en_US.txt cp -f ${repoDir}/zm-backup-store/build/dist/backup-version-init.sql ${ZCS_REL}/data cp -f ${repoDir}/zm-license-tools/build/zm-license-tools-*.jar ${ZCS_REL}/lib/jars/zimbra-license-tools.jar cp -f ${repoDir}/zm-network-licenses/thirdparty/oracle_jdk_eula.txt ${ZCS_REL}/docs/oracle_jdk_eula.txt cp -f ${repoDir}/zm-network-licenses/zimbra/zimbra_network_eula.txt ${ZCS_REL}/docs/zimbra_network_eula.txt cp -f ${repoDir}/zm-network-build/rpmconf/Install/Util/modules/postinstall.sh ${ZCS_REL}/util/modules cp -f ${repoDir}/zm-network-build/rpmconf/Util/checkValidBackup ${ZCS_REL}/bin/checkValidBackup chmod 755 ${ZCS_REL}/bin/checkValidBackup else cp -f ${repoDir}/zm-licenses/zimbra/zcl.txt ${ZCS_REL}/docs fi ########################################## if [ "${buildType}" == "NETWORK" ] then echo "NETWORK" > ${ZCS_REL}/.BUILD_TYPE else echo "FOSS" > ${ZCS_REL}/.BUILD_TYPE fi echo "${buildNo}" > ${ZCS_REL}/.BUILD_NUM echo "${os}" > ${ZCS_REL}/.BUILD_PLATFORM echo "${releaseNo}" > ${ZCS_REL}/.BUILD_RELEASE_NO echo "${releaseCandidate}" > ${ZCS_REL}/.BUILD_RELEASE_CANDIDATE echo "${buildTimeStamp}" > ${ZCS_REL}/.BUILD_TIME_STAMP ########################################## tar czf ${ZCS_REL}.tgz ${ZCS_REL} echo "ZCS build completed: ${repoDir}/zm-build/${ZCS_REL}.tgz" ================================================ FILE: instructions/bundling-scripts/zimbra-apache.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra apache package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-apache currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # apachebuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf echo -e "\tCopy package files" >> ${buildLogFile} cp ${repoDir}/zm-aspell/conf/httpd.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/httpd.conf cp ${repoDir}/zm-aspell/conf/php.ini ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/php.ini CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \./| |' \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" -e "s/@@branch@@/${buildTimeStamp}/" -e "s/@@ARCH@@/${arch}/" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os} /" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/^Copyright:/Copyright:/" > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf" >> ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/*" >> ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-core.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra core package #-------------------- Configuration --------------------------- currentScript="$(basename "$0" | cut -d "." -f 1)" # zimbra-core currentPackage="$(echo ${currentScript}build | cut -d "-" -f 2)" # corebuild #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { echo -e "\tCreate debian package" >> ${buildLogFile} mkdir -p "${repoDir}/zm-build/${currentPackage}/DEBIAN"; cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post > ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.pre > ${repoDir}/zm-build/${currentPackage}/DEBIAN/preinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/preinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst ( set -e; cd ${repoDir}/zm-build/${currentPackage} find . -type f -print0 \ | xargs -0 md5sum \ | grep -v -w "DEBIAN/.*" \ | sed -e "s@ [.][/]@ @" \ | sort \ ) > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums ( set -e; MORE_DEPENDS=", zimbra-timezone-data (>= 1.0.1+1510156506-1.$PKG_OS_TAG) $(find ${repoDir}/zm-packages/ -name \*.deb \ | xargs -n1 basename \ | sed -e 's/_[0-9].*//' \ | grep -e zimbra-common- \ | sed '1s/^/, /; :a; {N;s/\n/, /;ba}')"; cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb \ | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" \ -e "s/@@branch@@/${buildTimeStamp}/" \ -e "s/@@ARCH@@/${arch}/" \ -e "s/@@MORE_DEPENDS@@/${MORE_DEPENDS}/" \ -e "/^%post$/ r ${currentScript}.post" ) > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control ( set -e; cd ${repoDir}/zm-build/${currentPackage} dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch} ) } CreateRhelPackage() { MORE_DEPENDS=", zimbra-timezone-data >= 1.0.1+1510156506-1.$PKG_OS_TAG $(find ${repoDir}/zm-packages/ -name \*.rpm \ | xargs -n1 basename \ | sed -e 's/-[0-9].*//' \ | grep -e zimbra-common- \ | sed '1s/^/, /; :a; {N;s/\n/, /;ba}')"; cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/@@MORE_DEPENDS@@/${MORE_DEPENDS}/" \ -e "/^%pre$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.pre" \ -e "/Best email money can buy/ a Network edition" \ -e "/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post" > ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/corebuild; find opt -maxdepth 2 -type f -o -type l \ | sed -e 's|^|%attr(-, zimbra, zimbra) /|' >> \ ${repoDir}/zm-build/${currentScript}.spec ) echo "%attr(440, root, root) /etc/sudoers.d/01_zimbra" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(440, root, root) /etc/sudoers.d/02_zimbra-core" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, root, root) /opt/zimbra/bin" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/docs" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(444, zimbra, zimbra) /opt/zimbra/docs/*" >> \ ${repoDir}/zm-build/${currentScript}.spec if [ "${buildType}" == "NETWORK" ] then echo "%attr(755, zimbra, zimbra) /opt/zimbra/docs/rebranding" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(444, zimbra, zimbra) /opt/zimbra/docs/rebranding/*" >> \ ${repoDir}/zm-build/${currentScript}.spec fi echo "%attr(755, root, root) /opt/zimbra/contrib" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, root, root) /opt/zimbra/libexec" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/logger" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf/externaldirsync" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/externaldirsync/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf/sasl2" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/sasl2/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf/zmconfigd" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/zmconfigd/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/db" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/lib" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/conf/crontabs" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/lib/jylibs" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/lib/perl5/Zimbra" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/logger/db/work" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } #-------------------- main packaging --------------------------- main() { set -e Copy ${repoDir}/zm-build/rpmconf/Env/sudoers.d/01_zimbra ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/01_zimbra Copy ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_zimbra-core ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_zimbra-core Copy ${repoDir}/zm-amavis/conf/amavisd.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/amavisd.conf.in Copy ${repoDir}/zm-amavis/conf/amavisd/amavisd-custom.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/amavisd-custom.conf Copy ${repoDir}/zm-amavis/conf/dspam.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/dspam.conf.in Copy ${repoDir}/zm-build/lib/Zimbra/DB/DB.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/DB/DB.pm Copy ${repoDir}/zm-build/lib/Zimbra/LDAP.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/LDAP.pm Copy ${repoDir}/zm-build/lib/Zimbra/LocalConfig.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/LocalConfig.pm Copy ${repoDir}/zm-build/lib/Zimbra/Mon/Logger.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Mon/Logger.pm Copy ${repoDir}/zm-build/lib/Zimbra/Mon/LoggerSchema.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Mon/LoggerSchema.pm Copy ${repoDir}/zm-build/lib/Zimbra/Mon/Zmstat.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Mon/Zmstat.pm Copy ${repoDir}/zm-build/lib/Zimbra/SMTP.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SMTP.pm Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/Soap.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/Soap.pm Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/Soap11.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/Soap11.pm Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/Soap12.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/Soap12.pm Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/XmlDoc.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/XmlDoc.pm Copy ${repoDir}/zm-build/lib/Zimbra/SOAP/XmlElement.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/SOAP/XmlElement.pm Copy ${repoDir}/zm-build/lib/Zimbra/Util/Common.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Util/Common.pm Copy ${repoDir}/zm-build/lib/Zimbra/Util/LDAP.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Util/LDAP.pm Copy ${repoDir}/zm-build/lib/Zimbra/Util/Timezone.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/Util/Timezone.pm Copy ${repoDir}/zm-build/lib/Zimbra/ZmClient.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/perl5/Zimbra/ZmClient.pm Copy ${repoDir}/zm-build/rpmconf/Build/get_plat_tag.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/get_plat_tag.sh Copy ${repoDir}/zm-build/rpmconf/Build/get_plat_tag.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/bin/get_plat_tag.sh Copy ${repoDir}/zm-build/rpmconf/Conf/auditswatchrc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/auditswatchrc.in Copy ${repoDir}/zm-build/rpmconf/Conf/logswatchrc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/logswatchrc Copy ${repoDir}/zm-build/rpmconf/Conf/swatchrc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/swatchrc.in Copy ${repoDir}/zm-build/rpmconf/Conf/zmssl.cnf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmssl.cnf.in Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab.ldap ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab.ldap Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab.logger ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab.logger Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab.mta ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab.mta Copy ${repoDir}/zm-build/rpmconf/Env/crontabs/crontab.store ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/crontabs/crontab.store Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.bash_profile ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.bash_profile Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.bashrc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.bashrc Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.exrc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.exrc Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.ldaprc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.ldaprc Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.platform ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.platform Copy ${repoDir}/zm-build/rpmconf/Env/zimbra.viminfo ${repoDir}/zm-build/${currentPackage}/opt/zimbra/.viminfo Copy ${repoDir}/zm-build/rpmconf/Img/connection_failed.gif ${repoDir}/zm-build/${currentPackage}/opt/zimbra/logger/db/work/connection_failed.gif Copy ${repoDir}/zm-build/rpmconf/Img/data_not_available.gif ${repoDir}/zm-build/${currentPackage}/opt/zimbra/logger/db/work/data_not_available.gif Copy ${repoDir}/zm-build/rpmconf/Install/Util/addUser.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/addUser.sh Copy ${repoDir}/zm-build/rpmconf/Install/Util/addUser.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/addUser.sh Copy ${repoDir}/zm-build/rpmconf/Install/Util/globals.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/globals.sh Copy ${repoDir}/zm-build/rpmconf/Install/Util/modules/getconfig.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/modules/getconfig.sh Copy ${repoDir}/zm-build/rpmconf/Install/Util/modules/packages.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/modules/packages.sh Copy ${repoDir}/zm-build/rpmconf/Install/Util/modules/postinstall.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/modules/postinstall.sh Copy ${repoDir}/zm-build/rpmconf/Install/Util/utilfunc.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/utilfunc.sh Copy ${repoDir}/zm-build/rpmconf/Install/install.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/install.sh Copy ${repoDir}/zm-build/rpmconf/Install/postinstall.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/postinstall.pm Copy ${repoDir}/zm-build/rpmconf/Install/preinstall.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/preinstall.pm Copy ${repoDir}/zm-build/rpmconf/Install/zmsetup.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsetup.pl Copy ${repoDir}/zm-build/rpmconf/Upgrade/zmupgrade.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmupgrade.pm Copy ${repoDir}/zm-core-utils/conf/dhparam.pem.zcs ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/dhparam.pem.zcs Copy ${repoDir}/zm-core-utils/conf/zmlogrotate ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmlogrotate Copy ${repoDir}/zm-core-utils/src/bin/antispam-mysql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/antispam-mysql Copy ${repoDir}/zm-core-utils/src/bin/antispam-mysql.server ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/antispam-mysql.server Copy ${repoDir}/zm-core-utils/src/bin/antispam-mysqladmin ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/antispam-mysqladmin Copy ${repoDir}/zm-core-utils/src/bin/ldap.production ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/ldap Copy ${repoDir}/zm-core-utils/src/bin/mysql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/mysql Copy ${repoDir}/zm-core-utils/src/bin/mysql.server ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/mysql.server Copy ${repoDir}/zm-core-utils/src/bin/mysqladmin ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/mysqladmin Copy ${repoDir}/zm-core-utils/src/bin/postconf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/postconf Copy ${repoDir}/zm-core-utils/src/bin/postfix ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/postfix Copy ${repoDir}/zm-core-utils/src/bin/qshape ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/qshape Copy ${repoDir}/zm-core-utils/src/bin/zmaccts ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmaccts Copy ${repoDir}/zm-core-utils/src/bin/zmamavisdctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmamavisdctl Copy ${repoDir}/zm-core-utils/src/bin/zmantispamctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmantispamctl Copy ${repoDir}/zm-core-utils/src/bin/zmantispamdbpasswd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmantispamdbpasswd Copy ${repoDir}/zm-core-utils/src/bin/zmantivirusctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmantivirusctl Copy ${repoDir}/zm-core-utils/src/bin/zmapachectl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmapachectl Copy ${repoDir}/zm-core-utils/src/bin/zmarchivectl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmarchivectl Copy ${repoDir}/zm-core-utils/src/bin/zmauditswatchctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmauditswatchctl Copy ${repoDir}/zm-core-utils/src/bin/zmblobchk ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmblobchk Copy ${repoDir}/zm-core-utils/src/bin/zmcaldebug ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcaldebug Copy ${repoDir}/zm-core-utils/src/bin/zmcbpadmin ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcbpadmin Copy ${repoDir}/zm-core-utils/src/bin/zmcbpolicydctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcbpolicydctl Copy ${repoDir}/zm-core-utils/src/bin/zmcertmgr ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcertmgr Copy ${repoDir}/zm-core-utils/src/bin/zmclamdctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmclamdctl Copy ${repoDir}/zm-core-utils/src/bin/zmconfigdctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmconfigdctl Copy ${repoDir}/zm-core-utils/src/bin/zmcontactbackup ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcontactbackup Copy ${repoDir}/zm-core-utils/src/bin/zmcontrol ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmcontrol Copy ${repoDir}/zm-core-utils/src/bin/zmdedupe ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdedupe Copy ${repoDir}/zm-core-utils/src/bin/zmdhparam ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdhparam Copy ${repoDir}/zm-core-utils/src/bin/zmdnscachectl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdnscachectl Copy ${repoDir}/zm-core-utils/src/bin/zmdumpenv ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdumpenv Copy ${repoDir}/zm-core-utils/src/bin/zmfixcalendtime ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmfixcalendtime Copy ${repoDir}/zm-core-utils/src/bin/zmfixcalprio ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmfixcalprio Copy ${repoDir}/zm-core-utils/src/bin/zmfreshclamctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmfreshclamctl Copy ${repoDir}/zm-core-utils/src/bin/zmgsautil ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmgsautil Copy ${repoDir}/zm-core-utils/src/bin/zmhostname ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmhostname Copy ${repoDir}/zm-core-utils/src/bin/zminnotop ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zminnotop Copy ${repoDir}/zm-core-utils/src/bin/zmitemdatafile ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmitemdatafile Copy ${repoDir}/zm-core-utils/src/bin/zmjava ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmjava Copy ${repoDir}/zm-core-utils/src/bin/zmjavaext ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmjavaext Copy ${repoDir}/zm-core-utils/src/bin/zmldappasswd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmldappasswd Copy ${repoDir}/zm-core-utils/src/bin/zmldapupgrade ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmldapupgrade Copy ${repoDir}/zm-core-utils/src/bin/zmlmtpinject ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmlmtpinject Copy ${repoDir}/zm-core-utils/src/bin/zmlocalconfig ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmlocalconfig Copy ${repoDir}/zm-core-utils/src/bin/zmloggerctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmloggerctl Copy ${repoDir}/zm-core-utils/src/bin/zmloggerhostmap ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmloggerhostmap Copy ${repoDir}/zm-core-utils/src/bin/zmlogswatchctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmlogswatchctl Copy ${repoDir}/zm-core-utils/src/bin/zmmailbox ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmailbox Copy ${repoDir}/zm-core-utils/src/bin/zmmailboxdctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmailboxdctl Copy ${repoDir}/zm-core-utils/src/bin/zmmemcachedctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmemcachedctl Copy ${repoDir}/zm-core-utils/src/bin/zmmetadump ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmetadump Copy ${repoDir}/zm-core-utils/src/bin/zmmigrateattrs ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmigrateattrs Copy ${repoDir}/zm-core-utils/src/bin/zmmilterctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmilterctl Copy ${repoDir}/zm-core-utils/src/bin/zmmtactl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmtactl Copy ${repoDir}/zm-core-utils/src/bin/zmmypasswd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmypasswd Copy ${repoDir}/zm-core-utils/src/bin/zmmysqlstatus ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmysqlstatus Copy ${repoDir}/zm-core-utils/src/bin/zmmytop ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmytop Copy ${repoDir}/zm-core-utils/src/bin/zmopendkimctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmopendkimctl Copy ${repoDir}/zm-core-utils/src/bin/zmplayredo ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmplayredo Copy ${repoDir}/zm-core-utils/src/bin/zmprov ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmprov Copy ${repoDir}/zm-core-utils/src/bin/zmproxyconf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmproxyconf Copy ${repoDir}/zm-core-utils/src/bin/zmproxyctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmproxyctl Copy ${repoDir}/zm-core-utils/src/bin/zmpython ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmpython Copy ${repoDir}/zm-core-utils/src/bin/zmredodump ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmredodump Copy ${repoDir}/zm-core-utils/src/bin/zmsaslauthdctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmsaslauthdctl Copy ${repoDir}/zm-core-utils/src/bin/zmshutil ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmshutil Copy ${repoDir}/zm-core-utils/src/bin/zmskindeploy ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmskindeploy Copy ${repoDir}/zm-core-utils/src/bin/zmsoap ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmsoap Copy ${repoDir}/zm-core-utils/src/bin/zmspellctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmspellctl Copy ${repoDir}/zm-core-utils/src/bin/zmsshkeygen ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmsshkeygen Copy ${repoDir}/zm-core-utils/src/bin/zmstat-chart ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmstat-chart Copy ${repoDir}/zm-core-utils/src/bin/zmstat-chart-config ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmstat-chart-config Copy ${repoDir}/zm-core-utils/src/bin/zmstatctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmstatctl Copy ${repoDir}/zm-core-utils/src/bin/zmstorectl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmstorectl Copy ${repoDir}/zm-core-utils/src/bin/zmswatchctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmswatchctl Copy ${repoDir}/zm-core-utils/src/bin/zms3config ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zms3config Copy ${repoDir}/zm-core-utils/src/bin/zmthrdump ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmthrdump Copy ${repoDir}/zm-core-utils/src/bin/zmtlsctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmtlsctl Copy ${repoDir}/zm-core-utils/src/bin/zmtotp ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmtotp Copy ${repoDir}/zm-core-utils/src/bin/zmtrainsa ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmtrainsa Copy ${repoDir}/zm-core-utils/src/bin/zmtzupdate ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmtzupdate Copy ${repoDir}/zm-core-utils/src/bin/zmupdateauthkeys ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmupdateauthkeys Copy ${repoDir}/zm-core-utils/src/bin/zmvolume ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmvolume Copy ${repoDir}/zm-core-utils/src/bin/zmzimletctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmzimletctl Copy ${repoDir}/zm-core-utils/src/bin/zmonlyofficectl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmonlyofficectl Copy ${repoDir}/zm-core-utils/src/bin/zmrabbitmqctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmrabbitmqctl Copy ${repoDir}/zm-core-utils/src/bin/zmonlyofficeinstall ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmonlyofficeinstall Copy ${repoDir}/zm-core-utils/src/bin/zmlicensectl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmlicensectl Copy ${repoDir}/zm-core-utils/src/bin/zmacl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmacl Copy ${repoDir}/zm-core-utils/src/contrib/zmfetchercfg ${repoDir}/zm-build/${currentPackage}/opt/zimbra/contrib/zmfetchercfg Copy ${repoDir}/zm-core-utils/src/libexec/600.zimbra ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/600.zimbra Copy ${repoDir}/zm-core-utils/src/libexec/client_usage_report.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/client_usage_report.py Copy ${repoDir}/zm-core-utils/src/libexec/configrewrite ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/configrewrite Copy ${repoDir}/zm-core-utils/src/libexec/icalmig ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/icalmig Copy ${repoDir}/zm-core-utils/src/libexec/libreoffice-installer.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/libreoffice-installer.sh Copy ${repoDir}/zm-core-utils/src/libexec/zcs ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zcs Copy ${repoDir}/zm-core-utils/src/libexec/zimbra ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zimbra Copy ${repoDir}/zm-core-utils/src/libexec/zmaltermimeconfig ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmaltermimeconfig Copy ${repoDir}/zm-core-utils/src/libexec/zmantispamdbinit ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmantispamdbinit Copy ${repoDir}/zm-core-utils/src/libexec/zmantispammycnf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmantispammycnf Copy ${repoDir}/zm-core-utils/src/libexec/zmcbpolicydinit ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcbpolicydinit Copy ${repoDir}/zm-core-utils/src/libexec/zmcheckduplicatemysqld ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcheckduplicatemysqld Copy ${repoDir}/zm-core-utils/src/libexec/zmcheckexpiredcerts ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcheckexpiredcerts Copy ${repoDir}/zm-core-utils/src/libexec/zmcleantmp ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcleantmp Copy ${repoDir}/zm-core-utils/src/libexec/zmclientcertmgr ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmclientcertmgr Copy ${repoDir}/zm-core-utils/src/libexec/zmcompresslogs ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcompresslogs Copy ${repoDir}/zm-core-utils/src/libexec/zmcomputequotausage ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcomputequotausage Copy ${repoDir}/zm-core-utils/src/libexec/zmconfigd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmconfigd Copy ${repoDir}/zm-core-utils/src/libexec/zmcpustat ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmcpustat Copy ${repoDir}/zm-core-utils/src/libexec/zmdailyreport ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdailyreport Copy ${repoDir}/zm-core-utils/src/bin/zmpasswordexpiryreminder ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmpasswordexpiryreminder Copy ${repoDir}/zm-core-utils/src/libexec/zmdbintegrityreport ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdbintegrityreport Copy ${repoDir}/zm-core-utils/src/libexec/zmdiaglog ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdiaglog Copy ${repoDir}/zm-core-utils/src/libexec/zmdkimkeyutil ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdkimkeyutil Copy ${repoDir}/zm-core-utils/src/libexec/zmdnscachealign ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdnscachealign Copy ${repoDir}/zm-core-utils/src/libexec/zmdomaincertmgr ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmdomaincertmgr Copy ${repoDir}/zm-core-utils/src/libexec/zmexplainslow ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmexplainslow Copy ${repoDir}/zm-core-utils/src/libexec/zmexplainsql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmexplainsql Copy ${repoDir}/zm-core-utils/src/libexec/zmextractsql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmextractsql Copy ${repoDir}/zm-core-utils/src/libexec/zmfixperms ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmfixperms Copy ${repoDir}/zm-core-utils/src/libexec/zmfixreminder ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmfixreminder Copy ${repoDir}/zm-core-utils/src/libexec/zmgenentitlement ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmgenentitlement Copy ${repoDir}/zm-core-utils/src/libexec/zmgsaupdate ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmgsaupdate Copy ${repoDir}/zm-core-utils/src/libexec/zmhspreport ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmhspreport Copy ${repoDir}/zm-core-utils/src/libexec/zminiutil ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zminiutil Copy ${repoDir}/zm-core-utils/src/libexec/zmiostat ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmiostat Copy ${repoDir}/zm-core-utils/src/libexec/zmiptool ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmiptool Copy ${repoDir}/zm-core-utils/src/libexec/zmjavawatch ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmjavawatch Copy ${repoDir}/zm-core-utils/src/libexec/zmjettyenablelogging ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmjettyenablelogging Copy ${repoDir}/zm-core-utils/src/libexec/zmjsprecompile ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmjsprecompile Copy ${repoDir}/zm-core-utils/src/libexec/zmlogger ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmlogger Copy ${repoDir}/zm-core-utils/src/libexec/zmloggerinit ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmloggerinit Copy ${repoDir}/zm-core-utils/src/libexec/zmlogprocess ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmlogprocess Copy ${repoDir}/zm-core-utils/src/libexec/zmmsgtrace ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmsgtrace Copy ${repoDir}/zm-core-utils/src/libexec/zmmtainit ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmtainit Copy ${repoDir}/zm-core-utils/src/libexec/zmmtastatus ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmtastatus Copy ${repoDir}/zm-core-utils/src/libexec/zmmycnf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmycnf Copy ${repoDir}/zm-core-utils/src/libexec/zmmyinit ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmyinit Copy ${repoDir}/zm-core-utils/src/libexec/zmnotifyinstall ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmnotifyinstall Copy ${repoDir}/zm-core-utils/src/libexec/zmpostfixpolicyd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmpostfixpolicyd Copy ${repoDir}/zm-core-utils/src/libexec/zmproxyconfgen ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmproxyconfgen Copy ${repoDir}/zm-core-utils/src/libexec/zmproxyconfig ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmproxyconfig Copy ${repoDir}/zm-core-utils/src/libexec/zmproxypurge ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmproxypurge Copy ${repoDir}/zm-core-utils/src/libexec/zmqaction ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmqaction Copy ${repoDir}/zm-core-utils/src/libexec/zmqstat ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmqstat Copy ${repoDir}/zm-core-utils/src/libexec/zmqueuelog ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmqueuelog Copy ${repoDir}/zm-core-utils/src/libexec/zmrc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmrc Copy ${repoDir}/zm-core-utils/src/libexec/zmrcd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmrcd Copy ${repoDir}/zm-core-utils/src/libexec/zmresetmysqlpassword ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmresetmysqlpassword Copy ${repoDir}/zm-core-utils/src/libexec/zmrrdfetch ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmrrdfetch Copy ${repoDir}/zm-core-utils/src/libexec/zmsacompile ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsacompile Copy ${repoDir}/zm-core-utils/src/libexec/zmsaupdate ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsaupdate Copy ${repoDir}/zm-core-utils/src/libexec/zmserverips ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmserverips Copy ${repoDir}/zm-core-utils/src/libexec/zmsetservername ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsetservername Copy ${repoDir}/zm-core-utils/src/libexec/zmsnmpinit ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsnmpinit Copy ${repoDir}/zm-core-utils/src/libexec/zmspamextract ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmspamextract Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-allprocs ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-allprocs Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-cleanup ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-cleanup Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-convertd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-convertd Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-cpu ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-cpu Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-df ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-df Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-fd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-fd Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-io ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-io Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-mtaqueue ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-mtaqueue Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-mysql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-mysql Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-nginx ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-nginx Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-proc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-proc Copy ${repoDir}/zm-core-utils/src/libexec/zmstat-vm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-vm Copy ${repoDir}/zm-core-utils/src/libexec/zmstatuslog ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstatuslog Copy ${repoDir}/zm-core-utils/src/libexec/zmsyslogsetup ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmsyslogsetup Copy ${repoDir}/zm-core-utils/src/libexec/zmthreadcpu ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmthreadcpu Copy ${repoDir}/zm-core-utils/src/libexec/zmunbound ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmunbound Copy ${repoDir}/zm-core-utils/src/libexec/zmupdatedownload ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmupdatedownload Copy ${repoDir}/zm-core-utils/src/libexec/zmupdatezco ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmupdatezco Copy ${repoDir}/zm-core-utils/src/perl/migrate20131014-removezca.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20131014-removezca.pl Copy ${repoDir}/zm-db-conf/src/db/migration/Migrate.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/Migrate.pm Copy ${repoDir}/zm-db-conf/src/db/migration/clearArchivedFlag.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/clearArchivedFlag.pl Copy ${repoDir}/zm-db-conf/src/db/migration/fixConversationCounts.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/fixConversationCounts.pl Copy ${repoDir}/zm-db-conf/src/db/migration/fixZeroChangeIdItems.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/fixZeroChangeIdItems.pl Copy ${repoDir}/zm-db-conf/src/db/migration/fixup20080410-SetRsvpTrue.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/fixup20080410-SetRsvpTrue.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate-ComboUpdater.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate-ComboUpdater.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050517-AddUnreadColumn.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050517-AddUnreadColumn.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050531-RemoveCascadingDeletes.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050531-RemoveCascadingDeletes.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050609-AddDateIndex.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050609-AddDateIndex.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050628-ShrinkSyncColumns.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050628-ShrinkSyncColumns.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050701-SchemaCleanup.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050701-SchemaCleanup.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050721-MailItemIndexes.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050721-MailItemIndexes.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050727-RemoveTypeInvite.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050727-RemoveTypeInvite.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050727a-Volume.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050727a-Volume.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050804-SpamToJunk.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050804-SpamToJunk.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050809-AddConfig.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050809-AddConfig.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050811-WipeAppointments.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050811-WipeAppointments.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050818-TagsFlagsIndexes.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050818-TagsFlagsIndexes.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050822-TrackChangeDate.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050822-TrackChangeDate.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050824-AddMailTransport.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050824-AddMailTransport.sh Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050824a-Volume.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050824a-Volume.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050831-SecondaryMsgVolume.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050831-SecondaryMsgVolume.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050916-Volume.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050916-Volume.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050920-CompressionThreshold.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050920-CompressionThreshold.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20050927-DropRedologSequence.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20050927-DropRedologSequence.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20051021-UniqueVolume.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20051021-UniqueVolume.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060120-Appointment.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060120-Appointment.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060412-NotebookFolder.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060412-NotebookFolder.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060515-AddImapId.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060515-AddImapId.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060518-EmailedContactsFolder.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060518-EmailedContactsFolder.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060708-FlagCalendarFolder.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060708-FlagCalendarFolder.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060803-CreateMailboxMetadata.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060803-CreateMailboxMetadata.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060807-WikiDigestFixup.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060807-WikiDigestFixup.sh Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060810-PersistFolderCounts.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060810-PersistFolderCounts.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060911-MailboxGroup.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060911-MailboxGroup.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20060929-TypedTombstones.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20060929-TypedTombstones.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061101-IMFolder.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061101-IMFolder.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061117-TasksFolder.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061117-TasksFolder.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061120-AddNameColumn.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061120-AddNameColumn.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061204-CreatePop3MessageTable.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061204-CreatePop3MessageTable.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061205-UniqueAppointmentIndex.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061205-UniqueAppointmentIndex.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061212-RepairMutableIndexIds.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061212-RepairMutableIndexIds.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20061221-RecalculateFolderSizes.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20061221-RecalculateFolderSizes.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070302-NullContactVolumeId.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070302-NullContactVolumeId.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070306-Pop3MessageUid.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070306-Pop3MessageUid.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070606-WidenMetadata.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070606-WidenMetadata.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070614-BriefcaseFolder.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070614-BriefcaseFolder.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070627-BackupTime.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070627-BackupTime.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070629-IMTables.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070629-IMTables.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070630-LastSoapAccess.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070630-LastSoapAccess.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070703-ScheduledTask.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070703-ScheduledTask.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070706-DeletedAccount.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070706-DeletedAccount.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070713-NullContactBlobDigest.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070713-NullContactBlobDigest.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070725-CreateRevisionTable.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070725-CreateRevisionTable.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070726-ImapDataSource.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070726-ImapDataSource.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070809-Signatures.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070809-Signatures.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070921-ImapDataSourceUidValidity.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070921-ImapDataSourceUidValidity.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20070928-ScheduledTaskIndex.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20070928-ScheduledTaskIndex.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20071128-AccountId.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20071128-AccountId.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20071202-DeleteSignatures.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20071202-DeleteSignatures.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20071204-deleteOldLDAPUsers.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20071204-deleteOldLDAPUsers.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20071206-WidenSizeColumns.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20071206-WidenSizeColumns.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20080130-ImapFlags.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20080130-ImapFlags.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20080213-IndexDeferredColumn.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20080213-IndexDeferredColumn.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20080909-DataSourceItemTable.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20080909-DataSourceItemTable.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20080930-MucService.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20080930-MucService.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20090315-MobileDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20090315-MobileDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20090406-DataSourceItemTable.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20090406-DataSourceItemTable.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20090430-highestindexed.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20090430-highestindexed.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20100106-MobileDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20100106-MobileDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20100913-Mysql51.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20100913-Mysql51.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20100926-Dumpster.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20100926-Dumpster.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20101123-MobileDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20101123-MobileDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110314-MobileDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110314-MobileDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110330-RecipientsColumn.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110330-RecipientsColumn.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110705-PendingAclPush.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110705-PendingAclPush.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110810-TagTable.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110810-TagTable.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110928-MobileDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110928-MobileDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20110929-VersionColumn.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110929-VersionColumn.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20111005-ItemIdCheckpoint.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20111005-ItemIdCheckpoint.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120125-uuidAndDigest.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120125-uuidAndDigest.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120222-LastPurgeAtColumn.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120222-LastPurgeAtColumn.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120229-DropIMTables.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120229-DropIMTables.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120319-Name255Chars.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120319-Name255Chars.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120410-BlobLocator.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120410-BlobLocator.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20120611_7to8_bundle.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120611_7to8_bundle.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20121009-VolumeBlobs.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20121009-VolumeBlobs.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20130226_alwayson.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20130226_alwayson.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20130227-UpgradeCBPolicyDSchema.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20130227-UpgradeCBPolicyDSchema.sql Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20130606-UpdateCBPolicydSchema.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20130606-UpdateCBPolicydSchema.sql Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20130819-UpgradeQuotasTable.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20130819-UpgradeQuotasTable.sql Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20140319-MailItemPrevFolders.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20140319-MailItemPrevFolders.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20140328-EnforceTableCharset.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20140328-EnforceTableCharset.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20140624-DropMysqlIndexes.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20140624-DropMysqlIndexes.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20150401-ZmgDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150401-ZmgDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20150515-DataSourcePurgeTables.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150515-DataSourcePurgeTables.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20150623-ZmgDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150623-ZmgDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20150702-ZmgDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150702-ZmgDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20170301-ZimbraChat.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20170301-ZimbraChat.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20180301-ZimbraChat.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20180301-ZimbraChat.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20190401-ZimbraChat.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20190401-ZimbraChat.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20190611-ZimbraChat.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20190611-ZimbraChat.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20210506-BriefcaseApi.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20210506-BriefcaseApi.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20200625-MobileDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20200625-MobileDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20210319-MobileDevices.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20210319-MobileDevices.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20210809-UnsubscribeFolder.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20210809-UnsubscribeFolder.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20220525-Volume.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20220525-Volume.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20220721-AddMdmUpdateTimestamp.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20220721-AddMdmUpdateTimestamp.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20220729-FilesShareWithMeFolder.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20220729-FilesShareWithMeFolder.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrate20230224-UpdateOnlyOffice-7.2.1.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20230224-UpdateOnlyOffice-7.2.1.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateAmavisLdap20050810.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateAmavisLdap20050810.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateClearSpamFlag.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateClearSpamFlag.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLargeMetadata.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLargeMetadata.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger1-index.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger1-index.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger2-config.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger2-config.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger3-diskindex.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger3-diskindex.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger4-loghostname.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger4-loghostname.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger5-qid.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger5-qid.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateLogger6-qid.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateLogger6-qid.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateMailItemTimestamps.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateMailItemTimestamps.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migratePreWidenSizeColumns.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migratePreWidenSizeColumns.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateRemoveMailboxId.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateRemoveMailboxId.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateRemoveTagIndexes.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateRemoveTagIndexes.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateRenameIdentifiers.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateRenameIdentifiers.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateSyncSequence.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateSyncSequence.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateToSplitTables.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateToSplitTables.pl Copy ${repoDir}/zm-db-conf/src/db/migration/migrateUpdateAppointment.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrateUpdateAppointment.pl Copy ${repoDir}/zm-db-conf/src/db/migration/optimizeMboxgroups.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/optimizeMboxgroups.pl Copy ${repoDir}/zm-db-conf/src/db/migration/zmdbupgrade.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/zmdbupgrade.pl Copy ${repoDir}/zm-db-conf/src/db/mysql/create_database.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/db/create_database.sql Copy ${repoDir}/zm-db-conf/src/db/mysql/db.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/db/db.sql Copy ${repoDir}/zm-freshclam/freshclam.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/freshclam.conf.in Copy ${repoDir}/zm-jython/jylibs/commands.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/commands.py Copy ${repoDir}/zm-jython/jylibs/conf.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/conf.py Copy ${repoDir}/zm-jython/jylibs/config.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/config.py Copy ${repoDir}/zm-jython/jylibs/globalconfig.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/globalconfig.py Copy ${repoDir}/zm-jython/jylibs/ldap.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/ldap.py Copy ${repoDir}/zm-jython/jylibs/listener.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/listener.py Copy ${repoDir}/zm-jython/jylibs/localconfig.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/localconfig.py Copy ${repoDir}/zm-jython/jylibs/logmsg.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/logmsg.py Copy ${repoDir}/zm-jython/jylibs/miscconfig.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/miscconfig.py Copy ${repoDir}/zm-jython/jylibs/mtaconfig.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/mtaconfig.py Copy ${repoDir}/zm-jython/jylibs/serverconfig.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/serverconfig.py Copy ${repoDir}/zm-jython/jylibs/state.py ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/lib/jylibs/state.py Copy ${repoDir}/zm-launcher/build/dist/zmmailboxdmgr ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmailboxdmgr Copy ${repoDir}/zm-launcher/build/dist/zmmailboxdmgr.unrestricted ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmmailboxdmgr.unrestricted Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/Exchange2000.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/Exchange2000.xml Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/Exchange2003.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/Exchange2003.xml Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/Exchange5.5.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/Exchange5.5.xml Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/domino.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/domino.xml Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/novellGroupWise.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/novellGroupWise.xml Copy ${repoDir}/zm-ldap-utilities/conf/externaldirsync/openldap.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/externaldirsync/openldap.xml Copy ${repoDir}/zm-ldap-utilities/conf/freshclam.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/freshclam.conf.in Copy ${repoDir}/zm-ldap-utilities/conf/zmconfigd.cf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd.cf Copy ${repoDir}/zm-ldap-utilities/conf/zmconfigd.log4j.properties ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd.log4j.properties Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20110615-AddDynlist.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110615-AddDynlist.pl Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20110721-AddUnique.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20110721-AddUnique.pl Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20111019-UniqueZimbraId.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20111019-UniqueZimbraId.pl Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20120210-AddSearchNoOp.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120210-AddSearchNoOp.pl Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20120507-UniqueDKIMSelector.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20120507-UniqueDKIMSelector.pl Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20140728-AddSSHA512.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20140728-AddSSHA512.pl Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20141022-AddTLSBits.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20141022-AddTLSBits.pl Copy ${repoDir}/zm-ldap-utilities/src/ldap/migration/migrate20150930-AddSyncpovSessionlog.pl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/scripts/migrate20150930-AddSyncpovSessionlog.pl Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapanon ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapanon Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapapplyldif ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapapplyldif Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapenable-mmr ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapenable-mmr Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapenablereplica ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapenablereplica Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapinit ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapinit Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapmmrtool ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapmmrtool Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapmonitordb ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapmonitordb Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldappromote-replica-mmr ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldappromote-replica-mmr Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapreplicatool ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapreplicatool Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapschema ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapschema Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmldapupdateldif ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmldapupdateldif Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmreplchk ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmreplchk Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmslapadd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmslapadd Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmslapcat ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmslapcat Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmslapd ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmslapd Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmslapindex ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmslapindex Copy ${repoDir}/zm-ldap-utilities/src/libexec/zmstat-ldap ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmstat-ldap Copy ${repoDir}/zm-licenses/zimbra/ypl-full.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/YPL.txt Copy ${repoDir}/zm-licenses/zimbra/zpl-full.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/ZPL.txt Copy ${repoDir}/zm-migration-tools/ReadMe.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/zmztozmig.txt Copy ${repoDir}/zm-mta/cbpolicyd.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/cbpolicyd.conf.in Copy ${repoDir}/zm-mta/clamd.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/clamd.conf.in Copy ${repoDir}/zm-mta/opendkim-localnets.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/opendkim-localnets.conf.in Copy ${repoDir}/zm-mta/opendkim.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/opendkim.conf.in Copy ${repoDir}/zm-mta/postfix_header_checks.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/postfix_header_checks.in Copy ${repoDir}/zm-mta/postfix_sasl_smtpd.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/sasl2/smtpd.conf.in Copy ${repoDir}/zm-mta/salocal.cf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/salocal.cf.in Copy ${repoDir}/zm-mta/saslauthd.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/saslauthd.conf.in Copy ${repoDir}/zm-mta/zmconfigd/postfix_content_filter.cf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/postfix_content_filter.cf Copy ${repoDir}/zm-mta/zmconfigd/smtpd_end_of_data_restrictions.cf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_end_of_data_restrictions.cf Copy ${repoDir}/zm-mta/zmconfigd/smtpd_recipient_restrictions.cf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_recipient_restrictions.cf Copy ${repoDir}/zm-mta/zmconfigd/smtpd_relay_restrictions.cf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_relay_restrictions.cf Copy ${repoDir}/zm-mta/zmconfigd/smtpd_sender_login_maps.cf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_sender_login_maps.cf Copy ${repoDir}/zm-mta/zmconfigd/smtpd_sender_restrictions.cf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmconfigd/smtpd_sender_restrictions.cf Cpy2 ${repoDir}/junixsocket/junixsocket-native/build/junixsocket-native-*.nar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ Cpy2 ${repoDir}/junixsocket/junixsocket-native/build/libjunixsocket-native-*.so ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ Copy ${repoDir}/zm-bulkprovision-store/build/dist/commons-csv-1.2.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_bulkprovision/commons-csv-1.2.jar Copy ${repoDir}/zm-bulkprovision-store/build/dist/zm-bulkprovision-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_bulkprovision/com_zimbra_bulkprovision.jar Copy ${repoDir}/zm-certificate-manager-store/build/zm-certificate-manager-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_cert_manager/com_zimbra_cert_manager.jar # Copy SSDB Ephemeral storage extension + dependencies Cpy2 ${repoDir}/zm-ssdb-ephemeral-store/build/dist/zm-ssdb-ephemeral-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/ Cpy2 ${repoDir}/zm-zcs-lib/build/dist/jedis-2.9.0.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/ Cpy2 ${repoDir}/zm-zcs-lib/build/dist/commons-pool2-2.4.2.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/ if [ "${buildType}" == "NETWORK" ] then Copy ${repoDir}/zm-backup-store/docs/backup.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/backup.txt Copy ${repoDir}/zm-backup-store/docs/mailboxMove.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/mailboxMove.txt Copy ${repoDir}/zm-backup-store/docs/soapbackup.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/soapbackup.txt Copy ${repoDir}/zm-backup-store/docs/xml-meta.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/xml-meta.txt Copy ${repoDir}/zm-backup-store/build/dist/backup-version-init.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/db/backup-version-init.sql Copy ${repoDir}/zm-backup-utilities/src/bin/zmbackup ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmbackup Copy ${repoDir}/zm-backup-utilities/src/bin/zmbackupabort ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmbackupabort Copy ${repoDir}/zm-backup-utilities/src/bin/zmbackupquery ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmbackupquery Copy ${repoDir}/zm-backup-utilities/src/bin/zmmboxmove ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmboxmove Copy ${repoDir}/zm-backup-utilities/src/bin/zmmboxmovequery ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmboxmovequery Copy ${repoDir}/zm-backup-utilities/src/bin/zmpurgeoldmbox ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmpurgeoldmbox Copy ${repoDir}/zm-backup-utilities/src/bin/zmrestore ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmrestore Copy ${repoDir}/zm-backup-utilities/src/bin/zmrestoreldap ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmrestoreldap Copy ${repoDir}/zm-backup-utilities/src/bin/zmrestoreoffline ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmrestoreoffline Copy ${repoDir}/zm-backup-utilities/src/bin/zmschedulebackup ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmschedulebackup Copy ${repoDir}/zm-backup-utilities/src/db/backup_schema.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/db/backup_schema.sql Copy ${repoDir}/zm-backup-utilities/src/libexec/zmbackupldap ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmbackupldap Copy ${repoDir}/zm-backup-utilities/src/libexec/zmbackupqueryldap ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmbackupqueryldap Copy ${repoDir}/zm-convertd-native/conf/convertd.log4j.properties ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/convertd.log4j.properties Copy ${repoDir}/zm-convertd-native/src/bin/zmconvertctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmconvertctl Copy ${repoDir}/zm-convertd-native/src/libexec/zmconvertdmod ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/zmconvertdmod Copy ${repoDir}/zm-hsm/docs/soap-admin.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/hsm-soap-admin.txt Copy ${repoDir}/zm-network-build/rpmconf/Install/Util/modules/postinstall.sh ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/installer/util/modules/postinstall.sh Copy ${repoDir}/zm-network-build/rpmconf/Install/postinstall.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/postinstall.pm Copy ${repoDir}/zm-network-build/rpmconf/Install/preinstall.pm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/preinstall.pm Copy ${repoDir}/zm-network-licenses/thirdparty/oracle_jdk_eula.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/oracle_jdk_eula.txt Copy ${repoDir}/zm-postfixjournal/build/dist/postjournal ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/postjournal Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/DE_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/DE_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/ES_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/ES_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/FR_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/FR_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/IT_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/IT_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/JA_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/JA_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/NL_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/NL_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/RU_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/RU_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/en_US_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/en_US_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/pt_BR_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/pt_BR_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/zh_CN_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/zh_CN_Rebranding_directions.txt Copy ${repoDir}/zm-rebranding-docs/docs/rebranding/zh_HK_Rebranding_directions.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/rebranding/zh_HK_Rebranding_directions.txt Copy ${repoDir}/zm-twofactorauth-store/docs/twofactorauth.md ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/twofactorauth.md Copy ${repoDir}/zm-vmware-appmonitor/build/dist/libexec/vmware-appmonitor ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec/vmware-appmonitor Copy ${repoDir}/zm-vmware-appmonitor/build/dist/lib/libappmonitorlib.so ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/libappmonitorlib.so Copy ${repoDir}/zm-voice-store/docs/ZimbraVoice-Extension.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/ZimbraVoice-Extension.txt Copy ${repoDir}/zm-voice-store/docs/soap-voice-admin.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/soap-voice-admin.txt Copy ${repoDir}/zm-voice-store/docs/soap-voice.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/docs/soap-voice.txt fi CreatePackage "${os}" } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-dnscache.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra dnscache package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-dnscache currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # dnscachebuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/dns/ca mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/dns/trust CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* mkdir -p ${repoDir}/zm-build/${currentPackage}/etc/resolvconf/update.d cp ${repoDir}/zm-dnscache/conf/dns/zimbra-unbound ${repoDir}/zm-build/${currentPackage}/etc/resolvconf/update.d cp ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_${currentScript}.deb ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_${currentScript} echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \./| |' \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" \ -e "s/@@branch@@/${buildTimeStamp}/" -e "s/@@ARCH@@/${arch}/" -e "s/^Copyright:/Copyright:/" -e "/^%post$/ r ${currentPackage}.post" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { cp ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_${currentScript}.rpm ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_${currentScript} cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/^Copyright:/Copyright:/" \ -e "/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post" > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/data/dns" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(440, root, root) /etc/sudoers.d/02_zimbra-dnscache" >> \ ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-imapd.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2017 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra-imapd package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-imapd currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # imapbuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/jars echo -e "\tCopy package files" >> ${buildLogFile} cp ${repoDir}/zm-core-utils/src/bin/zmimapdctl ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmimapdctl cp ${repoDir}/zm-zcs-lib/build/dist/oauth-1.4.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/jars/oauth-1.4.jar cp ${repoDir}/zm-mailbox/store-conf/conf/imapd.log4j.properties ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/imapd.log4j.properties CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \./| |' \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" -e "s/@@branch@@/${buildTimeStamp}/" -e "s/@@ARCH@@/${arch}/" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/^Copyright:/Copyright:/" \ > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/bin/zmimapdctl" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/lib/jars/oauth-1.4.jar" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf/imapd.log4j.properties" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-ldap.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra ldap package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-ldap currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # ldapbuild ldapSchemaDir=${repoDir}/zm-ldap-utilities/build/dist #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/etc/openldap/zimbra echo -e "\tCopy package files" >> ${buildLogFile} cp -rf ${ldapSchemaDir}/* ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/etc/openldap/zimbra if [ "${buildType}" == "NETWORK" ] then cp -f ${repoDir}/zm-convertd-native/conf/ldap/zimbra_mimehandlers.ldif ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/etc/openldap/zimbra/convertd_mimehandlers.ldif fi CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \./| |' \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" -e "s/@@branch@@/${buildTimeStamp}/" -e "s/@@ARCH@@/${arch}/" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/^Copyright:/Copyright:/" \ -e "/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post" > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config/cn=config" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config/cn=config/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/config/cn=config/olcDatabase={2}mdb" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/schema" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/common/etc/openldap/zimbra/schema/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-logger.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra logger package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-logger currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # loggerbuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories..." >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/logger/db/data CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN echo -e "\tCopy package files..." >> ${buildLogFile} cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* echo -e "\tCreate debian package..." >> ${buildLogFile} cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" -e "s/@@branch@@/${buildTimeStamp}/" -e "s/@@ARCH@@/${arch}/" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/^Copyright:/Copyright:/" \ -e "/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post" > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/logger" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/logger/db" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/logger/db/data" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-mta.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra mta package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-mta currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # mtabuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/amavisd/mysql mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/altermime mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/cbpolicyd/db mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/clamav mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/opendkim mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/postfix echo -e "\tCopy package files" >> ${buildLogFile} cp ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_${currentScript} ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_${currentScript} cp ${repoDir}/zm-postfix/conf/postfix/master.cf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf/master.cf.in cp ${repoDir}/zm-postfix/conf/postfix/tag_as_foreign.re.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf/tag_as_foreign.re.in cp ${repoDir}/zm-postfix/conf/postfix/tag_as_originating.re.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf/tag_as_originating.re.in cp -f ${repoDir}/zm-amavis/conf/amavisd/mysql/antispamdb.sql ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/amavisd/mysql/antispamdb.sql CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*opt/zimbra/postfix-.*/conf/master.cf' ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | \ xargs -0 md5sum | sed -e 's| \./| |' > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" -e "s/@@branch@@/${buildTimeStamp}/" \ -e "s/@@ARCH@@/${arch}/" -e "s/@@ARCH@@/amd64/" -e "s/^Copyright:/Copyright:/" -e "/^%post$/ r ${currentScript}.post" > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/@@MTA_PROVIDES@@/smtpdaemon/" \ -e "s/^Copyright:/Copyright:/" \ -e "/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post" > ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/mtabuild; find opt -maxdepth 2 -type f -o -type l \ | sed -e 's|^|%attr(-, zimbra, zimbra) /|' >> \ ${repoDir}/zm-build/${currentScript}.spec ) echo "%attr(440, root, root) /etc/sudoers.d/02_zimbra-mta" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/common/conf/master.cf.in" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/common/conf/tag_as_foreign.re.in" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/common/conf/tag_as_originating.re.in" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/data/amavisd" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/data/clamav" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/data/cbpolicyd" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/data/opendkim" >> \ ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-proxy.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra proxy package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-proxy currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # proxybuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/nginx/includes mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/nginx/templates echo -e "\tCopy package files" >> ${buildLogFile} cp ${repoDir}/zm-nginx-conf/conf/nginx/* ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/nginx/templates/ CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex ".*?debian-binary.*" ! -regex ".*?DEBIAN.*" -print0 | xargs -0 md5sum | sed -e "s| \./| |" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" -e "s/@@branch@@/${buildTimeStamp}/" -e "s/@@ARCH@@/${arch}/" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch} ) } CreateRhelPackage() { cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/^Copyright:/Copyright:/" \ -e "/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post" > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf/nginx" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/nginx/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf/nginx/includes" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf/nginx/templates" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/nginx/templates/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-snmp.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra snmp package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-snmp currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # snmpbuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/snmp/persist mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/snmp/state mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/share/snmp/mibs echo -e "\tCopy package files" >> ${buildLogFile} cp ${repoDir}/zm-build/rpmconf/Conf/snmp.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/conf/snmp.conf cp ${repoDir}/zm-build/rpmconf/Conf/snmpd.conf.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/snmpd.conf.in cp ${repoDir}/zm-build/rpmconf/Conf/snmp.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/share/snmp/snmp.conf cp ${repoDir}/zm-build/rpmconf/Conf/mibs/*mib ${repoDir}/zm-build/${currentPackage}/opt/zimbra/common/share/snmp/mibs CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \./| |' \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" -e "s/@@branch@@/${buildTimeStamp}/" -e "s/@@ARCH@@/${arch}/" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/^Copyright:/Copyright:/" \ > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/data/snmp" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(775, root, zimbra) /opt/zimbra/common/conf" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, root, root) /opt/zimbra/common/conf/snmp.conf" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, root, root) /opt/zimbra/common/share/snmp" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, root, root) /opt/zimbra/common/share/snmp/snmp.conf" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, root, root) /opt/zimbra/common/share/snmp/mibs" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, root, root) /opt/zimbra/common/share/snmp/mibs/zimbra.mib" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, root, root) /opt/zimbra/common/share/snmp/mibs/zimbra_traps.mib" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-spell.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra spell package #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-spell currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # spellbuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/httpd/htdocs echo -e "\tCopy package files" >> ${buildLogFile} cp ${repoDir}/zm-aspell/src/php/aspell.php ${repoDir}/zm-build/${currentPackage}/opt/zimbra/data/httpd/htdocs/aspell.php CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | sed -e 's| \./| |' \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" -e "s/@@branch@@/${buildTimeStamp}/" -e "s/@@ARCH@@/${arch}/" \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/^Copyright:/Copyright:/" \ > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/data/httpd/htdocs/aspell.php" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: instructions/bundling-scripts/zimbra-store.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # Shell script to create zimbra store package set -e #-------------------- Configuration --------------------------- currentScript=`basename $0 | cut -d "." -f 1` # zimbra-store currentPackage=`echo ${currentScript}build | cut -d "-" -f 2` # storebuild #-------------------- Build Package --------------------------- main() { echo -e "\tCreate package directories" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/templates echo -e "\tCopy package files" >> ${buildLogFile} echo -e "\tCopy etc files" >> ${buildLogFile} cp ${repoDir}/zm-build/rpmconf/Env/sudoers.d/02_${currentScript} ${repoDir}/zm-build/${currentPackage}/etc/sudoers.d/02_${currentScript} echo -e "\tCopy bin files of /opt/zimbra/" >> ${buildLogFile} if [ "${buildType}" == "NETWORK" ] then cp -f ${repoDir}/zm-hsm-store/src/bin/zmmoveblobs ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmoveblobs cp -f ${repoDir}/zm-hsm/src/bin/zmhsm ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmhsm cp -f ${repoDir}/zm-hsm/src/bin/zmschedulesmpolicy ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmschedulesmpolicy cp -f ${repoDir}/zm-archive-utils/src/bin/zmarchiveconfig ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmarchiveconfig cp -f ${repoDir}/zm-archive-utils/src/bin/zmarchivesearch ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmarchivesearch cp -f ${repoDir}/zm-sync-tools/src/bin/zmsyncreverseproxy ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmsyncreverseproxy cp -f ${repoDir}/zm-sync-store/src/bin/zmdevicesstats ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmdevicesstats cp -f ${repoDir}/zm-sync-store/src/bin/zmgdcutil ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmgdcutil cp -f ${repoDir}/zm-sync-store/src/bin/zmmdmmailschedule ${repoDir}/zm-build/${currentPackage}/opt/zimbra/bin/zmmdmmailschedule fi cp -f ${repoDir}/zm-migration-tools/zmztozmig.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/zmztozmig.conf cp -f ${repoDir}/zm-mailbox/store-conf/conf/owasp_policy.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/owasp_policy.xml cp -f ${repoDir}/zm-mailbox/store-conf/conf/antisamy.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/antisamy.xml cp -f ${repoDir}/zm-mailbox/store-conf/conf/custom-mimetypes.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/conf/custom-mimetypes.xml echo -e "\tCopy extensions-extra files of /opt/zimbra/" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-extra/openidconsumer cp -rf ${repoDir}/zm-openid-consumer-store/build/dist/. ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-extra/openidconsumer rm -rf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-extra/openidconsumer/extensions-extra if [ "${buildType}" == "NETWORK" ] then echo -e "\tCopy extensions-network-extra files of /op/zimbra/" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-network-extra cp -rf ${repoDir}/zm-saml-consumer-store/build/dist/saml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/extensions-network-extra/ fi echo -e "\tCopy lib files of /opt/zimbra/" >> ${buildLogFile} echo -e "\t\tCopy ext files of /opt/zimbra/lib/" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/jars mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/mitel mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/clamscanner mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/twofactorauth mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/nginx-lookup mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/openidconsumer mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-license mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-freebusy mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbraadminversioncheck mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbraldaputils mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-oauth-social mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-gql mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common if [ "${buildType}" == "NETWORK" ] then mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/backup mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-archive mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/voice mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/mitel mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/cisco mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrasync mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/network mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_oo mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/convertd mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrahsm mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/smime mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-doc-server-ext cp -f ${repoDir}/zm-backup-store/build/dist/zm-backup-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/backup/zimbrabackup.jar cp -f ${repoDir}/zm-backup-store/build/dist/rocksdbjni-8.1.1.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/backup/rocksdbjni-8.1.1.jar cp -f ${repoDir}/zm-backup-store/build/dist/zstd-jni-1.5.5-9.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/backup/zstd-jni-1.5.5-9.jar cp -f ${repoDir}/zm-archive-store/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-archive/zimbra-archive.jar cp -rf ${repoDir}/zm-voice-store/build/dist/zm-voice-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/voice/zimbravoice.jar cp -rf ${repoDir}/zm-voice-mitel-store/build/dist/zm-voice-mitel-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/mitel cp -rf ${repoDir}/zm-voice-cisco-store/build/dist/zm-voice-cisco-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/cisco cp -rf ${repoDir}/zm-sync-common/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrasync cp -rf ${repoDir}/zm-sync-store/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrasync cp -rf ${repoDir}/zm-sync-tools/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrasync cp -f ${repoDir}/zm-openoffice-store/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_oo mv ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_oo/zm-openoffice-store.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/com_zimbra_oo/com_zimbra_oo.jar cp -rf ${repoDir}/zm-convertd-store/build/dist/*jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/convertd cp -f ${repoDir}/zm-twofactorauth-store/build/dist/zm-twofactorauth-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/twofactorauth/zimbratwofactorauth.jar cp -f ${repoDir}/zm-hsm-store/build/zimbrahsm.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrahsm/zimbrahsm.jar cp -f ${repoDir}/zm-store-managers/build/zm-store-managers*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbrahsm/zm-store-managers.jar cp -f ${repoDir}/zm-freebusy-provider-store/build/zimbra-freebusyprovider.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbra-freebusy/zimbra-freebusyprovider.jar cp -rf ${repoDir}/zm-smime-store/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/smime cp -f ${repoDir}/zm-network-gql/build/dist/zm-network-gql*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-gql/zmnetworkgql.jar cp -f ${repoDir}/zm-zcs-lib/build/dist/tika-app-1.24.1.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/convertd/ cp -rf ${repoDir}/zm-doc-server-ext/build/dist/*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-doc-server-ext fi cp -f ${repoDir}/zm-clam-scanner-store/build/dist/zm-clam-scanner-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/clamscanner/clamscanner.jar cp -f ${repoDir}/zm-nginx-lookup-store/build/dist/zm-nginx-lookup-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/nginx-lookup/nginx-lookup.jar cp -f ${repoDir}/zm-openid-consumer-store/build/dist/guice*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/openidconsumer/ cp -f ${repoDir}/zm-versioncheck-store/build/zm-versioncheck-store*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbraadminversioncheck/zimbraadminversioncheck.jar cp -f ${repoDir}/zm-ldap-utils-store/build/zm-ldap-utils-*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zimbraldaputils/zimbraldaputils.jar cp -f ${repoDir}/zm-oauth-social/build/dist/zm-oauth-social.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-oauth-social/zmoauthsocial.jar cp -f ${repoDir}/zm-oauth-social/build/dist/zm-oauth-social-common.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/zm-oauth-social-common.jar cp -f ${repoDir}/zm-zcs-lib/build/dist/java-jwt-3.2.0.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-oauth-social/ cp -f ${repoDir}/zm-gql/build/dist/zm-gql*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext/zm-gql/zmgql.jar #-------------------- Get wars content (service.war, zimbra.war and zimbraAdmin.war) --------------------------- echo "\t\t++++++++++ service.war content ++++++++++" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/ mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/service/WEB-INF/lib cp ${repoDir}/zm-zimlets/conf/zimbra.tld ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/service/WEB-INF cp ${repoDir}/zm-taglib/build/zm-taglib*.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/service/WEB-INF/lib cp ${repoDir}/zm-zimlets/build/dist/zimlettaglib.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/service/WEB-INF/lib mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra if [ "${buildType}" == "NETWORK" ] then echo "\t\t***** css, public and t content *****" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/css mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/public fi echo "\t\t***** portals example content *****" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/portals/example cp -rf ${repoDir}/zm-webclient-portal-example/example ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/portals echo "\t\t***** robots.txt content *****" >> ${buildLogFile} cp -f ${repoDir}/zm-aspell/conf/robots.txt ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/robots.txt echo "\t\t***** downloads content *****" >> ${buildLogFile} downloadsDir=${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbra/downloads mkdir -p ${downloadsDir} cp -rf ${repoDir}/zm-downloads/. ${downloadsDir} if [ "${buildType}" == "NETWORK" ] then set -e cd ${downloadsDir} # wget -r -nd --no-parent --reject-regex="/backup/" --reject "index.*" http://${zimbraThirdPartyServer}/ZimbraThirdParty/zco-migration-builds/current/ # zimbraThirdPartyServer Could be S3 bucket name. rclone copy -v ${zimbraThirdPartyServer}/ZimbraThirdParty/zco-migration-builds/current/ ./ fi echo "\t\t***** help content *****" >> ${buildLogFile} rsync -a ${repoDir}/zm-admin-help-common/WebRoot/help ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbraAdmin/ if [ "${buildType}" == "NETWORK" ] then rsync -a ${repoDir}/zm-admin-help-network/WebRoot/help ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/webapps/zimbraAdmin/ fi if [ "${buildType}" == "NETWORK" ] then echo -e "\t\tCopy ext-common files of /opt/zimbra/lib/" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common cp -f ${repoDir}/zm-zcs-lib/build/dist/bcpkix-jdk15on-1.64.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/ cp -f ${repoDir}/zm-zcs-lib/build/dist/bcmail-jdk15on-1.64.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/ cp -f ${repoDir}/zm-zcs-lib/build/dist/bcprov-jdk15on-1.64.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/ cp -f ${repoDir}/zm-zcs-lib/build/dist/saaj-impl-1.5.1.jar ${repoDir}/zm-build/${currentPackage}/opt/zimbra/lib/ext-common/ fi cp -f ${repoDir}/zm-migration-tools/src/libexec/zmztozmig ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec cp -f ${repoDir}/zm-migration-tools/src/libexec/zmcleaniplanetics ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec cp -f ${repoDir}/zm-versioncheck-utilities/src/libexec/zmcheckversion ${repoDir}/zm-build/${currentPackage}/opt/zimbra/libexec echo -e "\tCopy log files of /opt/zimbra/" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/log cp -f ${repoDir}/zm-build/rpmconf/Conf/hotspot_compiler ${repoDir}/zm-build/${currentPackage}/opt/zimbra/log/.hotspot_compiler echo -e "\tCopy zimlets files of /opt/zimbra/" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets zimletsArray=( "zm-versioncheck-admin-zimlet" \ "zm-bulkprovision-admin-zimlet" \ "zm-certificate-manager-admin-zimlet" \ "zm-proxy-config-admin-zimlet" \ "zm-helptooltip-zimlet" \ "zm-viewmail-admin-zimlet" ) for i in "${zimletsArray[@]}" do cp ${repoDir}/${i}/build/zimlet/*.zip ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets done cp -f ${repoDir}/zm-zimlets/build/dist/zimlets/*.zip ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets if [ "${buildType}" == "NETWORK" ] then echo -e "\tCopy zimlets-network files of /opt/zimbra/" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets-network adminZimlets=( "zm-license-admin-zimlet" \ "zm-backup-restore-admin-zimlet" \ "zm-convertd-admin-zimlet" \ "zm-delegated-admin-zimlet" \ "zm-hsm-admin-zimlet" \ "zm-smime-cert-admin-zimlet" \ "zm-2fa-admin-zimlet" \ "zm-ucconfig-admin-zimlet" \ "zm-securemail-zimlet" \ "zm-mobile-sync-admin-zimlet" ) for i in "${adminZimlets[@]}" do cp ${repoDir}/${i}/build/zimlet/*.zip ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets-network done adminUcZimlets=( "cisco" "mitel" "voiceprefs" ) for i in "${adminUcZimlets[@]}" do cp ${repoDir}/zm-uc-admin-zimlets/${i}/build/zimlet/*.zip ${repoDir}/zm-build/${currentPackage}/opt/zimbra/zimlets-network done fi echo "\t\t***** Building jetty/common/ *****" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/common/endorsed mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/common/lib mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/temp touch ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/temp/.emptyfile echo -e "\tCreate jetty conf" >> ${buildLogFile} mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/modules mkdir -p ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/start.d cp -f ${repoDir}/zm-jetty-conf/conf/jetty/jettyrc ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/ cp -f ${repoDir}/zm-jetty-conf/conf/jetty/zimbra.policy.example ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/ cp -f ${repoDir}/zm-jetty-conf/conf/jetty/jetty.xml.production ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/jetty.xml.in cp -f ${repoDir}/zm-jetty-conf/conf/jetty/webdefault.xml.production ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/webdefault.xml cp -f ${repoDir}/zm-jetty-conf/conf/jetty/jetty-setuid.xml ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/jetty-setuid.xml cp -f ${repoDir}/zm-jetty-conf/conf/jetty/spnego/etc/spnego.properties ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/spnego.properties.in cp -f ${repoDir}/zm-jetty-conf/conf/jetty/spnego/etc/spnego.conf ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/spnego.conf.in cp -f ${repoDir}/zm-jetty-conf/conf/jetty/spnego/etc/krb5.ini ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/krb5.ini.in cp -f ${repoDir}/zm-jetty-conf/conf/jetty/modules/*.mod ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/modules cp -f ${repoDir}/zm-jetty-conf/conf/jetty/modules/*.mod.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/modules cp -f ${repoDir}/zm-jetty-conf/conf/jetty/start.d/*.ini.in ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/start.d cp -f ${repoDir}/zm-jetty-conf/conf/jetty/modules/npn/*.mod ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/modules/npn cp -f ${repoDir}/zm-jetty-conf/conf/jetty/jetty-logging.properties ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/ cp -f ${repoDir}/zm-zimlets/conf/web.xml.production ${repoDir}/zm-build/${currentPackage}/opt/zimbra/jetty_base/etc/zimlet.web.xml.in CreatePackage "${os}" } #-------------------- Util Functions --------------------------- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/utils.sh" CreateDebianPackage() { mkdir -p ${repoDir}/zm-build/${currentPackage}/DEBIAN cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.pre >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/preinst cat ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post >> ${repoDir}/zm-build/${currentPackage}/DEBIAN/postinst chmod 555 ${repoDir}/zm-build/${currentPackage}/DEBIAN/* echo -e "\tCreate debian package" >> ${buildLogFile} (cd ${repoDir}/zm-build/${currentPackage}; find . -type f ! -regex '.*jetty_base/webapps/zimbra/WEB-INF/jetty-env.xml' ! \ -regex '.*jetty_base/webapps/zimbraAdmin/WEB-INF/jetty-env.xml' ! -regex '.*jetty_base/modules/setuid.mod' ! \ -regex '.*jetty_base/etc/krb5.ini' ! -regex '.*jetty_base/etc/spnego.properties' ! -regex '.*jetty_base/etc/jetty.xml' ! \ -regex '.*jetty_base/etc/spnego.conf' ! -regex '.*jetty_base/webapps/zimbraAdmin/WEB-INF/web.xml' ! \ -regex '.*jetty_base/webapps/zimbra/WEB-INF/web.xml' ! -regex '.*jetty_base/webapps/service/WEB-INF/web.xml' ! \ -regex '.*jetty_base/work/.*' ! -regex '.*.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' -print0 | xargs -0 md5sum | \sed -e 's| \./| |' \ > ${repoDir}/zm-build/${currentPackage}/DEBIAN/md5sums) ( set -e MORE_DEPENDS="$(find ${repoDir}/zm-packages/ -name \*.deb \ | xargs -n1 basename \ | sed -e 's/_[0-9].*//' \ | grep -e zimbra-mbox- \ | sed '1s/^/, /; :a; {N;s/\n/, /;ba}')"; cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.deb \ | sed -e "s/@@VERSION@@/${releaseNo}.${releaseCandidate}.${buildNo}.${os/_/.}/" \ -e "s/@@branch@@/${buildTimeStamp}/" \ -e "s/@@ARCH@@/${arch}/" \ -e "s/@@MORE_DEPENDS@@/${MORE_DEPENDS}/" \ -e "s/@@PKG_OS_TAG@@/${PKG_OS_TAG}/" \ -e "/^%post$/ r ${currentScript}.post" ) > ${repoDir}/zm-build/${currentPackage}/DEBIAN/control (cd ${repoDir}/zm-build/${currentPackage}; dpkg -b ${repoDir}/zm-build/${currentPackage} ${repoDir}/zm-build/${arch}) } CreateRhelPackage() { MORE_DEPENDS="$(find ${repoDir}/zm-packages/ -name \*.rpm \ | xargs -n1 basename \ | sed -e 's/-[0-9].*//' \ | grep -e zimbra-mbox- \ | sed '1s/^/, /; :a; {N;s/\n/, /;ba}')"; cat ${repoDir}/zm-build/rpmconf/Spec/${currentScript}.spec | \ sed -e "s/@@VERSION@@/${releaseNo}_${releaseCandidate}_${buildNo}.${os}/" \ -e "s/@@RELEASE@@/${buildTimeStamp}/" \ -e "s/@@MORE_DEPENDS@@/${MORE_DEPENDS}/" \ -e "s/@@PKG_OS_TAG@@/${PKG_OS_TAG}/" \ -e "/^%pre$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.pre" \ -e "/^%post$/ r ${repoDir}/zm-build/rpmconf/Spec/Scripts/${currentScript}.post" > ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, root, root) /opt/zimbra/lib" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(440, root, root) /etc/sudoers.d/02_zimbra-store" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, zimbra, zimbra) /opt/zimbra/conf" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(644, zimbra, zimbra) /opt/zimbra/conf/*" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/log" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/zimlets" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/extensions-extra" >> \ ${repoDir}/zm-build/${currentScript}.spec if [ "${buildType}" == "NETWORK" ] then echo "%attr(-, zimbra, zimbra) /opt/zimbra/zimlets-network" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/extensions-network-extra" >> \ ${repoDir}/zm-build/${currentScript}.spec fi echo "%attr(755, root, root) /opt/zimbra/bin" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(755, root, root) /opt/zimbra/libexec" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "%attr(-, zimbra, zimbra) /opt/zimbra/jetty_base" >> \ ${repoDir}/zm-build/${currentScript}.spec echo "" >> ${repoDir}/zm-build/${currentScript}.spec echo "%clean" >> ${repoDir}/zm-build/${currentScript}.spec (cd ${repoDir}/zm-build/${currentPackage}; \ rpmbuild --target ${arch} --define '_rpmdir ../' --buildroot=${repoDir}/zm-build/${currentPackage} -bb ${repoDir}/zm-build/${currentScript}.spec ) } ############################################################################ main "$@" ================================================ FILE: lib/Zimbra/DB/DB.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package Zimbra::DB::DB; use strict; ############# my $MYSQL = "mysql"; my $DB_USER = "zimbra"; my $DB_PASSWORD = "zimbra"; my $database = "zimbra"; my $ZMLOCALCONFIG = "/opt/zimbra/bin/zmlocalconfig"; if ($^O !~ /MSWin/i) { $DB_PASSWORD = `$ZMLOCALCONFIG -s -m nokey zimbra_mysql_password`; chomp $DB_PASSWORD; $DB_USER = `$ZMLOCALCONFIG -m nokey zimbra_mysql_user`; chomp $DB_USER; $MYSQL = "/opt/zimbra/bin/mysql"; } sub getDatabase() { return $database; } sub setDatabase($) { $database = shift(); } sub getMailboxIds() { return runSql("SELECT id FROM mailbox ORDER BY id"); } sub runSql(@) { my ($script, $logSql) = @_; if (! defined($logSql)) { $logSql = 1; } # Write the last script to a text file for debugging # open(LASTSCRIPT, ">lastScript.sql") || die "Could not open lastScript.sql"; # print(LASTSCRIPT $script); # close(LASTSCRIPT); if ($logSql) { Zimbra::DB::DB::log($script); } # Run the mysql command and redirect output to a temp file my $tempFile = "/tmp/mysql.out.$$"; my $command = "$MYSQL --user=$DB_USER --password=$DB_PASSWORD " . "--database=$database --batch --skip-column-names"; open(MYSQL, "| $command > $tempFile") || die "Unable to run $command"; print(MYSQL $script); close(MYSQL); if ($? != 0) { die "Error while running '$command'."; } # Process output open(OUTPUT, $tempFile) || die "Could not open $tempFile"; my @output; while () { s/\s+$//; push(@output, $_); } unlink($tempFile); return @output; } sub log { print scalar(localtime()), ": ", @_, "\n"; } 1; ================================================ FILE: lib/Zimbra/LDAP.pm ================================================ package Zimbra::LDAP; use strict; use warnings; use Zimbra::LocalConfig; use Net::LDAP; my $ERROR; my $TLSVERIFY = "require"; # "none" my $CAPATH = "/opt/zimbra/conf/ca"; =head1 NAME Zimbra::LDAP - Access to Zimbra LDAP directory =head1 SYNOPSIS my $zl = Zimbra::LDAP->new; my $global = $zl->global; my $server = $zl->server('mail.zimbra.com'); my $admin = $zl->mail('admin@mail.zimbra.com'); print $global->get_value("zimbraSmtpHostname") , "\n"; print $server->get_value("zimbraSmtpHostname") , "\n"; print $admin->get_value("cn") , "\n"; # when default settings are not what you need use Zimbra::LocalConfig; use Zimbra::LDAP; my $zlc = Zimbra::LocalConfig->new( file => "some non-default file" ) ; # when working with multiple environments create multiple objects my $zl = Zimbra::LDAP->new( dn => $zlc->get('my local config dn'), # grab from config password => $zlc->get('my local config password'), # grab from config config => $zlc, # pass in custom local config url => $zlc->get('my url') # grab from config ); =head1 DESCRIPTION Perl API for interacting with the Zimbra LDAP server. =head1 CONSTRUCTOR =head2 new Creates new instance of Zimbra::LDAP. New supports passing in the following values: =over =item url =item dn =item password =item config =back See each of the above methods for more details about each value. my $zl = Zimbra::LDAP->new; my $zl = Zimbra::LDAP->new( dn => "my dn", password => "my dn password" ); =cut sub new { my $class = shift; my %args = @_; my $self = {}; bless $self, $class; foreach my $key ( keys %args ) { if ( $self->can($key) ) { unless ( $self->$key( $args{$key} ) ) { return; } } } return unless ( $self->config ); return unless ( $self->ldap ); return $self; } =head1 PROPERTIES =head2 error Returns last error message. print Zimbra::LDAP->error, "\n"; print $zl->error, "\n"; =cut sub error { $ERROR = $_[1] if ($#_); return $ERROR; } =head2 config Returns the Zimbra::LocalConfig object. print $zl->config->get("ldap_url"), "\n"; =cut sub config { $_[0]->{_config} = $_[1] if ($#_); # allow new to assign value unless ( exists( $_[0]->{_config} ) ) { unless ( $_[0]->{_config} = Zimbra::LocalConfig->new ) { $_[0]->error( "Zimbra::LocalConfig error: " . Zimbra::LocalConfig->error ); return; } } return $_[0]->{_config}; } =head2 dn Returns the local config zimbra_ldap_userdn or the dn value passed during new. print $zl->dn, "\n"; =cut sub dn { $_[0]->{_dn} = $_[1] if ($#_); # allow new to assign value $_[0]->{_dn} = $_[0]->config->get("zimbra_ldap_userdn") unless ( exists( $_[0]->{_dn} ) ); # assign default dn; return $_[0]->{_dn}; } =head2 password Returns the local config zimbra_ldap_password or the password value passed during new. print $zl->password, "\n"; =cut sub password { $_[0]->{_password} = $_[1] if ($#_); # allow new to assign value $_[0]->{_password} = $_[0]->config->get("zimbra_ldap_password") unless ( exists( $_[0]->{_password} ) ); # assign default password; return $_[0]->{_password}; } =head2 url Returns the local config ldap_url or the value url value passed during new. print $zl->url, "\n"; =cut sub url { $_[0]->{_url} = $_[1] if ($#_); # allow new to assign value $_[0]->{_url} = $_[0]->config->get("ldap_url") unless ( exists( $_[0]->{_url} ) ); # assign default url; return $_[0]->{_url}; } =head2 ldap Returns the Net::LDAP object. my $result = $zl->ldap->search(...); =cut sub ldap { unless ( exists( $_[0]->{_ldap} ) ) { if ( my $ldapurl = $_[0]->url ) { my $servers = [ split( / /, $ldapurl ) ]; # connect to ldap server unless ( $_[0]->{_ldap} = Net::LDAP->new($servers) ) { delete( $_[0]->{_ldap} ); $_[0]->error( "Failed to connect to LDAP (" . join( " ", @$servers ) . "):" . $@ ); return; } #print "LDAP Host: ",$_[0]->{_ldap}->host," ",$_[0]->{_ldap}->scheme," ", # $_[0]->config->get("ldap_starttls_supported"),"\n"; # start TLS if desired if ( $_[0]->{_ldap}->scheme !~ /^ldaps$/i ) { if ( $_[0]->config->get("ldap_starttls_supported") ) { my $mesg = $_[0]->{_ldap}->start_tls( verify => $TLSVERIFY, capath => $CAPATH ); if ( $mesg->code ) { $_[0]->error( "start tls failed: " . $mesg->error ); return; } } } # bind ldap my $mesg = $_[0]->{_ldap}->bind( $_[0]->dn, password => $_[0]->password ); if ( $mesg->code ) { $_[0]->error( "bind failed: " . $mesg->error ); return; } } else { $_[0]->error("ldap_url not defined in localconfig"); return; } } return $_[0]->{_ldap}; } =head2 global Returns Net::LDAP::Entry for the Zimbra global config LDAP entry. print $zl->global->get_value("zimbraSmtpHostname"), "\n"; =cut sub global { unless ( exists( $_[0]->{_global} ) ) { $_[0]->{_global} = $_[0]->searchsingle( scope => "base", base => "cn=config,cn=zimbra", filter => "cn=config" ); } return $_[0]->{_global}; } =head1 METHODS =head2 mail Returns Net::LDAP::Entry for the passed mail address. my $admin=$zl->mail('admin@mail.zimbra.com'); =cut sub mail { my $self = shift; my $mail = shift; return $self->searchsingle( filter => "(mail=$mail)" ); } =head2 searchsingle Passes all arguments to Net::LDAP search method and checks that we only get one result and returns that specific Net::LDAP::Entry value. my $mail = $zl->searchsingle( filter => "(mail=$mail)" ); unless ($mail) { print $zl->error, "\n"; } =cut sub searchsingle { my ( $self, %args ) = @_; my $mesg = $self->ldap->search(%args); my $count = $mesg->count; if ( $count != 1 ) { $self->error("$count matches for '$args{filter}'"); return; } return $mesg->entry(0); } =head2 server Returns Net::LDAP::Entry for the passed server name. my $server = $zl->server('mail.zimbra.com'); =cut sub server { my $self = shift; my $host = shift; return $self->searchsingle( base => "cn=servers,cn=zimbra", filter => "(cn=$host)" ); } =head1 SEE ALSO L, L =cut 1; ================================================ FILE: lib/Zimbra/LocalConfig.pm ================================================ package Zimbra::LocalConfig; use strict; use warnings; use XML::Simple; my $ERROR; =head1 NAME Zimbra::LocalConfig - Read access to all Zimbra local config values =head1 SYNOPSIS use Zimbra::LocalConfig; my $zlc = Zimbra::LocalConfig->new; print $zlc->get('ldap_url'), "\n"; =head1 DESCRIPTION Perl API for accessing zimbra local config values. =head1 CONSTRUCTOR =head2 new Creates new instance of Zimbra::LocalConfig. my $zlc = Zimbra::LocalConfig->new; my $zlc = Zimbra::LocalConfig->new(file=>"my zimbra config xml file"); =cut sub new { my $class = shift; my %args = @_; my $self = {}; bless $self, $class; foreach my $key ( keys %args ) { if ( $self->can($key) ) { unless ( $self->$key( $args{$key} ) ) { return; } } } return unless ( $self->xml ); return $self; } =head1 PROPERTIES =head2 error Returns last error message. print Zimbra::LocalConfig->error, "\n"; print $zlc->error, "\n"; =cut sub error { $ERROR = $_[1] if ($#_); return $ERROR; } =head2 file Returns the local config file name. Defaults to: /opt/zimbra/conf/localconfig.xml print $zlc->file, "\n"; =cut sub file { $_[0]->{_file} = $_[1] if ($#_); # allow new to assign value $_[0]->{_file} = "/opt/zimbra/conf/localconfig.xml" unless ( exists( $_[0]->{_file} ) ); # assign default file; return $_[0]->{_file}; } =head2 xml Returns HASH representation of XML file. print $zlc->xml->{key}{ldap_url}, "\n"; =cut sub xml { $_[0]->{_xml} = $_[1] if ($#_); # allow new to assign value unless ( exists( $_[0]->{_xml} ) ) { unless ( $_[0]->{_xml} = XMLin( $_[0]->file ) ) { $_[0]->error( "failed to open " . $_[0]->file . ": " . $@ ); return; } } return $_[0]->{_xml}; } =head1 METHODS =head2 get Get passed local config value. my $ldapurl = $zlc->get('ldap_url'); =cut sub get { if ( exists( $_[0]->xml->{key}{ $_[1] } ) ) { return $_[0]->xml->{key}{ $_[1] }{value}; } else { return; } } =head1 SEE ALSO L =cut 1; ================================================ FILE: lib/Zimbra/Mon/Logger.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # #!/usr/bin/perl package Zimbra::Mon::Logger; use strict; use Sys::Syslog qw(:DEFAULT setlogsock);; use Data::UUID; require Exporter; my @ISA = qw(Exporter); my $ident="zimbramon"; my $facility="local0"; my $stats_facility = "local1"; my @EXPORT = qw (Log); our %loglevels = ('debug' => 0, 'info' => 1, 'err' => 3, 'crit' => 4); my $LOG_LEVEL = $loglevels{'info'}; my $ug = new Data::UUID; sub Log { my ($level,$msg) = (@_); if ($loglevels{$level} >= $LOG_LEVEL) { # native is a better choice but unix provide a consistent output # across multiple nodes that makes parsing easier setlogsock('unix'); eval { openlog($ident, "pid,ndelay,nowait,nofatal", $facility); }; return if ($@); if (length($msg) <= 800) { syslog($level, "$$:$level: $msg"); } else { my $last_uuid = undef; my $m = $msg; do { my $substring = substr $m, 0, 800; $m = substr $m, 800; if (defined $last_uuid) { $substring = ":::${last_uuid}:::${substring}"; } $last_uuid = $ug->to_string($ug->create()); syslog($level, "$$:$level: ${substring}:::${last_uuid}:::"); } while (length($m) > 800); syslog($level, ":::${last_uuid}:::${m}"); } if ($::DEBUG) { print STDERR scalar localtime().":$$:$level: $msg\n"; } closelog(); } } sub LogStats { my ($level,$msg) = (@_); if ($loglevels{$level} >= $LOG_LEVEL) { setlogsock('unix'); eval { openlog($ident, "pid,ndelay,nowait,nofatal", $stats_facility);}; return if ($@); if (length($msg) <= 800) { syslog($level, "$$:$level: $msg"); } else { my $last_uuid = undef; my $m = $msg; do { my $substring = substr $m, 0, 800; $m = substr $m, 800; if (defined $last_uuid) { $substring = ":::${last_uuid}:::${substring}"; } $last_uuid = $ug->to_string($ug->create()); syslog($level, "$$:$level: ${substring}:::${last_uuid}:::"); } while (length($m) > 800); syslog($level, ":::${last_uuid}:::${m}"); } if ($::DEBUG) { print STDERR scalar localtime().":$$:$level: $msg\n"; } closelog(); } } 1 ================================================ FILE: lib/Zimbra/Mon/LoggerSchema.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package Zimbra::Mon::LoggerSchema; use strict; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(@LOGGER_SCHEMA_UPGRADE); our @LOGGER_SCHEMA_UPGRADE = ( # version 0, schema version [ q{ CREATE TABLE config ( version INTEGER NOT NULL UNIQUE ) }, q{ INSERT INTO config VALUES (0); } ], # version 1, column mapping [ q{ CREATE TABLE rrd_column_type ( csv_file varchar(255) not null, col_name varchar(255) not null, -- G-AUGE, C-OUNTER, A-BSOLUTE or D-ERIVED col_type char(1) not null, col_interval integer, CONSTRAINT unqcoltype UNIQUE (csv_file, col_name) ) }, # sqlite's version of multiple insert # # by default, all columns will have an interval of 30s # and type of GAUGE (i.e. columns not in this table) q{ INSERT INTO rrd_column_type select 'mailboxd.csv', 'gc_minor_ms', 'C', 30 union all select 'mailboxd.csv', 'gc_minor_count', 'C', 30 union all select 'mailboxd.csv', 'gc_major_ms', 'C', 30 union all select 'mailboxd.csv', 'gc_major_count', 'C', 30 union all select 'mysql.csv', 'Slow_queries', 'C', 30 union all select 'mysql.csv', 'Opened_tables', 'C', 30 union all select 'df.csv', 'disk_pct_used', 'G', 600 union all select 'df.csv', 'disk_use', 'G', 600 union all select 'df.csv', 'disk_space', 'G', 600 union all select 'zmmtastats', 'clam_events', 'A', 300 union all select 'zmmtastats', 'sendmail_events','A', 300 union all select 'zmmtastats', 'filter_count', 'A', 300 union all select 'zmmtastats', 'filter_virus', 'A', 300 union all select 'zmmtastats', 'filter_spam', 'A', 300 union all select 'zmmtastats', 'filter_misc', 'A', 300 union all select 'zmmtastats', 'mta_count', 'A', 300 union all select 'zmmtastats', 'mta_volume', 'A', 300 }, q{ UPDATE config SET version = 1 } ], # version 2, column globs [ q{ UPDATE rrd_column_type SET col_interval = 60 WHERE csv_file = 'mailboxd.csv' }, q{ INSERT INTO rrd_column_type select 'mailboxd.csv', '*', 'G', 60 union all select 'zmstatuslog', '*', 'G', 120 }, q{ UPDATE config SET version = 2 } ], # version 3, counter types [ q{ ALTER table rrd_column_type ADD COLUMN col_unit varchar(64) }, q{ UPDATE rrd_column_type SET col_unit = '% time', col_interval = 60 WHERE col_name IN ('gc_minor_ms', 'gc_major_ms') }, q{ UPDATE rrd_column_type SET col_unit = 'times/second', col_interval = 60 WHERE col_name IN ('gc_minor_count', 'gc_major_count') }, q{ UPDATE rrd_column_type SET col_unit = 'queries/s' WHERE col_name = 'Slow_queries' }, q{ UPDATE rrd_column_type SET col_unit = 'opens/s' WHERE col_name = 'Opened_tables' }, q{ UPDATE rrd_column_type SET col_unit = 'bytes' WHERE col_name IN ('disk_use', 'disk_space') }, q{ UPDATE rrd_column_type SET col_unit = 'events/s' WHERE col_name IN ('clam_events', 'sendmail_events') }, q{ UPDATE rrd_column_type SET col_unit = 'filter/s' WHERE col_name IN ('filter_count', 'filter_misc', 'filter_virus', 'filter_spam') }, q{ UPDATE rrd_column_type SET col_unit = 'msgs/s' WHERE col_name = 'mta_count' }, q{ UPDATE rrd_column_type SET col_unit = 'bytes/s' WHERE col_name = 'mta_volume' }, q{ INSERT INTO rrd_column_type select 'mysql.csv', '*', 'G', 30, null }, q{ INSERT INTO rrd_column_type select 'mtaqueue.csv', 'requests', 'G', 30, 'msgs' union all select 'fd.csv', 'fd_count', 'G', 30, 'fd' union all select 'cpu.csv', '*', 'G', 30, '% cpu' union all select 'vmstat.csv', 'pageins', 'G', 30, 'KB/s' union all select 'vmstat.csv', 'si', 'G', 30, 'KB/s' union all select 'vmstat.csv', 'pageout', 'G', 30, 'KB/s' union all select 'vmstat.csv', 'so', 'G', 30, 'KB/s' union all select 'vmstat.csv', 'free', 'G', 30, 'KB' union all select 'vmstat.csv', 'active', 'G', 30, 'KB' union all select 'vmstat.csv', 'inac', 'G', 30, 'KB' union all select 'vmstat.csv', 'Active', 'G', 30, 'KB' union all select 'vmstat.csv', 'Inactive', 'G', 30, 'KB' union all select 'vmstat.csv', 'cache', 'G', 30, 'KB' union all select 'vmstat.csv', 'cs', 'G', 30, 'cs/s' union all select 'vmstat.csv', 'r', 'G', 30, 'run-q' union all select 'vmstat.csv', 'b', 'G', 30, 'io-q' union all select 'vmstat.csv', 'loadavg', 'G', 30, null union all select 'soap.csv', 'exec_count', 'A', 30, 'calls/s' union all select 'soap.csv', 'exec_ms_avg', 'G', 30, null union all select 'mailboxd.csv', 'mbox_add_msg_count','A', 30, 'add/s' union all select 'mailboxd.csv', 'soap_count', 'A', 30, 'op/s' union all select 'mailboxd.csv', 'imap_count', 'A', 30, 'op/s' union all select 'mailboxd.csv', 'pop_count', 'A', 30, 'op/s' union all select 'mailboxd.csv', 'mbox_msg_cache', 'G', 30, 'cache hit %' union all select 'mailboxd.csv', 'mbox_item_cache', 'G', 30, 'cache hit %' union all select 'convertd.csv', 'cputime', 'G', 30, 'seconds/100' union all select 'convertd.csv', 'stime', 'G', 30, 'seconds/100' union all select 'convertd.csv', 'utime', 'G', 30, 'seconds/100' union all select 'convertd.csv', 'rss', 'G', 30, 'KB' union all select 'allprocs.csv', 'cputime', 'G', 30, 'seconds' union all select 'nginx.csv', 'cputime', 'G', 30, 'seconds/100' union all select 'nginx.csv', 'stime', 'G', 30, 'seconds/100' union all select 'nginx.csv', 'utime', 'G', 30, 'seconds/100' union all select 'nginx.csv', 'rss', 'G', 30, 'KB' }, q{ UPDATE config SET version = 3 }, ], [ q{ DELETE FROM rrds WHERE csv_file = 'allprocs.csv'; }, q{ UPDATE config SET version = 4 }, ], ); 1; ================================================ FILE: lib/Zimbra/Mon/Zmstat.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package Zimbra::Mon::Zmstat; use Exporter; @ISA = qw(Exporter); @EXPORT = qw( zmstatInit getZimbraUser getZimbraServerHostname getZmstatRoot getZmstatInterval isLinux isMac percent getTstamp getDate waitUntilNiceRoundSecond getPidFileDir readPidFile createPidFile getLogFilePath openLogFile rotateLogFile readLine ); use strict; use File::Basename; use FileHandle; our %LC; sub getLocalConfig(;@) { my @vars = @_; my $dir = dirname($0); my $cmd = "/opt/zimbra/bin/zmlocalconfig -q -x"; if (scalar(@vars) > 0) { $cmd .= ' ' . join(' ', @vars); } open(LCH, "$cmd |") or die "Unable to invoke $cmd: $!"; my $line; while (defined($line = )) { $line =~ s/[\r\n]*$//; # Remove trailing CR/LFs. my @fields = split(/\s*=\s*/, $line, 2); $LC{$fields[0]} = $fields[1]; } close(LCH); } sub userCheck() { my $loggedIn = `id -un`; chomp($loggedIn) if (defined($loggedIn)); my $expected = $LC{zimbra_user}; if ($loggedIn ne $expected) { print STDERR "Must be user $expected to run this command\n"; exit(1); } } sub isLinux() { return $^O =~ /linux/i; } sub isMac() { return $^O =~ /darwin/i; } sub osCheck() { if (!isLinux() && !isMac()) { print "zmstat is supported on Linux and Mac only\n"; exit(0); # return success to calling script } } sub zmstatInit() { osCheck(); getLocalConfig('zimbra_user', 'zimbra_server_hostname', 'zmstat_interval', 'zmstat_disk_interval'); userCheck(); } sub getZimbraUser() { return $LC{'zimbra_user'}; } sub getZimbraServerHostname() { return $LC{'zimbra_server_hostname'}; } sub getZmstatRoot() { return "/opt/zimbra/zmstat"; } sub getZmstatInterval() { my $n = $LC{'zmstat_interval'}; if (!defined($n) || $n + 0 < 1) { $n = 30; } return $n; } sub percent($$) { my ($val, $total) = @_; return sprintf("%.1f", $total > 0 ? $val * 100 / $total : 0); } sub getTstamp() { my ($sec, $min, $hour, $mday, $mon, $year) = localtime(); return sprintf("%02d/%02d/%04d %02d:%02d:%02d", $mon + 1, $mday, $year + 1900, $hour, $min, $sec); } sub getDate() { my ($sec, $min, $hour, $mday, $mon, $year) = localtime(); return sprintf("%04d-%02d-%02d", $year + 1900, $mon + 1, $mday); } sub waitUntilNiceRoundSecond($) { # Maximum interval allowed is 1 day (24 * 60 * 60 seconds) my $maxInterval = 24 * 60 * 60; my $interval = shift; $interval %= $maxInterval; $interval = $interval ? $interval : $maxInterval; while (1) { my ($sec, $min, $hour) = localtime(); my $t = $hour * 60 * 60 + $min * 60 + $sec; my $howlong = $t % $interval; last if ($howlong == 0); select(undef, undef, undef, 0.05); } return time; } sub getPidFileDir() { return getZmstatRoot() . "/pid"; } sub readPidFile($) { my $file = shift; my $pid = undef; if (open(PID, "< $file")) { $pid = ; close(PID); chomp($pid) if (defined($pid)); } return $pid; } # Check pid file to see if this process is a duplicate. # If not, create the pid file. sub createPidFile($) { my $name = shift; my $zmstatDir = getZmstatRoot(); my $pidDir = getPidFileDir(); my $pidFile = "$pidDir/$name"; if (-e $pidFile) { my $pid = readPidFile($pidFile); if ($pid) { if (kill(0, $pid)) { # Already running. print STDERR "$name: Already running as pid $pid\n"; exit(0); } unlink($pidFile); } } if (! -e $zmstatDir) { die "$zmstatDir does not exist"; } if (! -e $pidDir) { mkdir($pidDir, 0755); } open(PID, "> $pidFile") || die "Unable to create pid file $pidFile: $!"; print PID "$$\n"; close(PID); } sub getLogFilePath($) { my $fname = shift; return getZmstatRoot() . "/$fname"; } sub openLogFile($;$) { my ($logfile, $heading) = @_; my $fh = new FileHandle; if (defined($logfile) && $logfile ne '' && $logfile ne '-') { my $dir = File::Basename::dirname($logfile); if (! -e $dir) { mkdir($dir, 0755) || die "Unable to create log directory $dir: $!"; my (undef,undef,$uid,$gid) = getpwnam('zimbra'); chown $uid,$gid,$dir; } if (-f $logfile) { # check for stale data my $stale = 0; my $date = ""; my $today = getDate(); $fh->open("<$logfile") || die "Unable to read existing logfile: $!"; while (<$fh>) { if (/^(\d{2})\/(\d{2})\/(\d{4})/o) { $date = "$3-$1-$2"; } } $stale = 1 if $date ne $today; if ($stale) { print STDERR "$logfile was stale ($date) pre-rotating\n"; return rotateLogFile($fh, $logfile, $heading, $date); } $fh->close(); } $fh->open(">> $logfile") || die "Unable to open log file $logfile: $!"; } else { $fh = *STDOUT; } if ($heading) { $fh->print($heading); $fh->print("\n"); $fh->flush(); } return $fh; } sub rotateLogFile($$;$$) { my ($fh, $logfile, $heading, $date) = @_; my ($name, $path) = File::Basename::fileparse($logfile); if (!defined($date)) { $date = getDate(); } my $rotatedir = "$path/$date"; mkdir($rotatedir, 0755); if (! -d $rotatedir) { die "Unable to create log rotation directory $rotatedir"; } my (undef,undef,$uid,$gid) = getpwnam('zimbra'); chown $uid,$gid,$rotatedir; $fh->close() if defined $fh; my $rotatefile = "$rotatedir/$name"; # If previous .gz is there, unzip it. my $rotateGz = "$rotatefile.gz"; if (-e $rotateGz) { if (-e $rotatefile) { unlink($rotatefile); } system("gzip -d $rotateGz"); } # Rename or concatenate, with gzip. if (! -e $rotatefile) { my $rc = system("cat $logfile | gzip -c > $rotateGz"); $rc >>= 8; if ($rc) { die "Unable to move $logfile to $rotateGz"; } unlink($logfile); } else { my $rc = system("cat $rotatefile $logfile | gzip -c > $rotateGz"); $rc >>= 8; if ($rc) { die "Unable to concatenate $logfile and $rotatefile to $rotateGz"; } unlink($rotatefile, $logfile); } return openLogFile($logfile, $heading); } sub readLine($$) { my ($rh, $skip_empty) = @_; my $line = ''; while ($line eq '') { $line = <$rh>; return if (!defined($line)); # EOF chomp($line); last if (!$skip_empty); } return $line; } 1; ================================================ FILE: lib/Zimbra/SMTP.pm ================================================ package Zimbra::SMTP; use strict; use warnings; use Zimbra::LDAP; use Net::SMTP; use Net::DNS; my $ERROR; =head1 NAME Zimbra::SMTP - Access to Zimbra SMTP mail servers =head1 SYNOPSIS my $zs = Zimbra::SMTP->new; $zs->send( to => 'abc@zimbra.com', from => 'xyz@zimbra.com', subject => 'testing', message => 'test' ); =head1 DESCRIPTION Perl API for sending SMTP messages through Zimbra MTA. =head1 CONSTRUCTOR =head2 new Creates new instance of Zimbra::SMTP. my $zs = Zimbra::SMTP->new; =cut sub new { my $class = shift; my $self = {}; bless $self, $class; return unless ( $self->ldap ); return $self; } =head1 PROPERTIES =head2 error Returns last error message. print Zimbra::SMTP->error, "\n"; print $zs->error, "\n"; =cut sub error { $ERROR = $_[1] if ($#_); return $ERROR; } =head2 ldap Returns the Zimbra::LDAP object. print $zs->ldap->config->get("ldap_url"), "\n"; =cut sub ldap { unless ( exists( $_[0]->{_ldap} ) ) { unless ( $_[0]->{_ldap} = Zimbra::LDAP->new ) { $_[0]->error( "failed to connect to LDAP: " . Zimbra::LDAP->error ); return; } } return $_[0]->{_ldap}; } =head2 smtp Returns the Net::SMTP object. We try to find the most appropriate MTA to use with Net::SMTP in this order: =over =item servers zimbra ldap zimbraSmtpHostname and zimbraSmtpPort =item global zimbra ldap zimbraSmtpHostname and zimbraSmtpPort =item localhost port 25 =item DNS MX record for destination domain =back print $zs->smtp->domain, "\n"; =cut sub smtp { unless ( exists( $_[0]->{_smtp} ) ) { foreach my $try ( "_server", "_global", "_local", "_domain" ) { my ( $server, $port ) = $_[0]->$try( $_[1] ); if ( $_[0]->{_smtp} = Net::SMTP->new( Host => $server, Port => $port, Timeout => 10 ) ) { #print "SMTP ", $try, " ", $server, " ", $port, "\n"; return $_[0]->{_smtp}; } } delete( $_[0]->{_smtp} ); $_[0]->error("failed to find available SMTP server"); return; } return $_[0]->{_smtp}; } sub _server { my $ls = $_[0]->ldap->server( $_[0]->ldap->config->get("zimbra_server_hostname") ); my $server = $ls->get_value("zimbraSmtpHostname"); my $port = $ls->get_value("zimbraSmtpPort") || 25; return $server, $port; } sub _global { return $_[0]->ldap->global->get_value("zimbraSmtpHostname"), $_[0]->ldap->global->get_value("zimbraSmtpPort") || 25; } sub _local { return "localhost", 25; } sub _domain { my $server = undef; my $dns = new Net::DNS::Resolver; if ( my $mx = $dns->query( $_[1], 'MX' ) ) { if ( my $rr = ( $mx->answer )[0] ) { $server = $rr->exchange; } } return $server, 25; } =head1 METHODS =head2 send Send email message using smtp. Send support the following named arguments: =over =item to Specifies e-mail address to send message to. =item from Specifies e-mail address the message is from. =item subject Specifies e-mail subject. =item message Specifies e-mail content. =back $zs->send( to => 'abc@zimbra.com', from => 'xyz@zimbra.com', subject => 'testing', message => 'test' ); =cut sub send { my ( $self, %args ) = @_; my $domain = $args{to}; $domain =~ s/^[^\@]+\@//; unless ( $self->smtp($domain) ) { return; } if ( $self->smtp ) { $self->smtp->mail( $args{from} ); $self->smtp->to( $args{to} ); my @message = "To: $args{to}\n"; push( @message, "From: $args{from}\n" ); push( @message, "Subject: ", $args{subject}, "\n" ) if ( exists( $args{subject} ) ); push( @message, "\n" ); push( @message, $args{message}, "\n" ) if ( exists( $args{message} ) ); $self->smtp->data(@message); return 1; } return; } =head2 SEE ALSO L, L, L =cut 1; ================================================ FILE: lib/Zimbra/SOAP/Soap.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package Zimbra::SOAP::Soap; use strict; use warnings; use XML::Parser; use LWP::UserAgent; use Zimbra::SOAP::XmlElement; use Zimbra::SOAP::Soap12; use Zimbra::SOAP::Soap11; #use overload '""' => \&to_string; BEGIN { use Exporter (); our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); # set the version for version checking $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw(); %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], # your exported package globals go here, # as well as any optionally exported functions @EXPORT_OK = qw(); } our @EXPORT_OK; our $Soap12 = new Zimbra::SOAP::Soap12; our $Soap11 = new Zimbra::SOAP::Soap11; # # given a XmlElement, wrap it in a SOAP envelope and return the envelope # sub soapEnvelope { die "must override"; } # # Return Content-Type header # sub getContentType() { die "must override"; } # # Return the namespace String # sub getNamespace { die "must override"; } # # Return charset encoding for converting from bytes/strings # sub getCharSet { return "UTF-8"; } # # Convert a SOAP message in a String to bytes # sub convertToBytes { die "not implemented yet"; } # # Convert a SOAP message in bytes to a String # sub convertToString { die "not implemented yet"; } # # return the first child in the soap body # sub getElement { die "must override"; } # # Returns true if this element represents a SOAP fault # sub isFault { die "must override"; } # # Returns true if this soap envelope has a SOAP fault as the # first child of its body. # sub hasFault { my ($self, $e) = @_; return $self->isFault($e->child(0)); } # # determine if given element is Soap11 or Soap12 envelope, # and returns the Soap11 or Soap12 instance, or undef if neither. # sub determineProtocol { my $e = shift; return undef unless $e->name() eq "Envelope"; return $Soap12 if ($e->ns() eq $Soap12->getNamespace()); return $Soap11 if ($e->ns() eq $Soap11->getNamespace()); return undef; } # # Whether or not to include a HTTP SOAPActionHeader. (Gag) # sub hasSOAPActionHeader { die "must override"; } # # returns the version as a string (e.g, "1.1" or "1.2") # sub getVersion { die "must override"; } # sub toString { my $self = shift; return "SOAP ".$self->getVersion(); } sub zimbraContext { my ($self, $authtoken) = @_; my $context = new Zimbra::SOAP::XmlElement("context", "urn:zimbra"); my $auth = new Zimbra::SOAP::XmlElement("authToken"); $auth->content($authtoken); $context->add_child($auth); return $context; } # simple invoke method for now, this will get replaced sub invoke { my ($self, $uri, $doc, $context, $timeout) = @_; my $env = $self->soapEnvelope($doc, $context); my $soap = $env->to_string(); #print "REQUEST:\n" . $env->to_string('pretty') . "\n"; my $ua = new LWP::UserAgent(); if (defined($timeout) && $timeout > 0) { $ua->timeout($timeout); # timeout in seconds } my $req = new HTTP::Request(POST=> $uri); $req->content_type($self->getContentType()); $req->content_length(length($soap)); if ($self->hasSOAPActionHeader()) { $req->header("SOAPAction" => $uri); } $req->add_content($soap); my $res = $ua->request($req); if (!defined($res)) { print STDERR "No response from server\n"; return undef; } my $xml = undef; eval { $xml = Zimbra::SOAP::XmlElement::parse($res->content); }; if (!defined($xml)) { # Check for network/HTTP error after trying XML parse because # a SOAP fault comes back with HTTP 500 status. if ($res->is_error()) { print STDERR "SOAP request failed: code=" . $res->code() . ", error=" . $res->message() . "\n"; } else { # We have legitimate XML parse error. print STDERR "Unable to parse SOAP response: " . $res->content() . "\n"; } return undef; } my $rsoap = determineProtocol($xml); if (!defined($rsoap)) { print STDERR "Unable to determine SOAP protocol\n"; return undef; } elsif ($rsoap != $self) { print STDERR "Unexpected SOAP version in response\n"; return undef; } my $resp = $self->getElement($xml); #print "RESPONSE:\n" . $resp->to_string('pretty') . "\n" if defined($resp); if ($self->isFault($resp)) { my $faultParsed = 0; my $reason = $resp->find_child('Reason'); if (defined($reason)) { my $text = $reason->find_child('Text'); if (defined($text)) { print STDERR "Received SOAP fault: " . $text->content() . "\n"; $faultParsed = 1; } } if (!$faultParsed) { print STDERR "Received SOAP fault: " . $resp->to_string('pretty') . "\n"; } return undef; } return $resp; } 1; ================================================ FILE: lib/Zimbra/SOAP/Soap11.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package Zimbra::SOAP::Soap11; use strict; use warnings; use XML::Parser; use Zimbra::SOAP::XmlElement; #use overload '""' => \&to_string; BEGIN { use Exporter (); our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); # set the version for version checking $VERSION = 1.00; @ISA = qw(Exporter Zimbra::SOAP::Soap); @EXPORT = qw(); %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], # your exported package globals go here, # as well as any optionally exported functions @EXPORT_OK = qw(); } our @EXPORT_OK; our $NS = "http://schemas.xmlsoap.org/soap/envelope/"; sub new { my $type = shift; my $self = {}; bless $self, $type; return $self; } # # given a XmlElement, wrap it in a SOAP envelope and return the envelope # sub soapEnvelope { my $self = shift; my $e = shift; my $context = shift; my $env = new Zimbra::SOAP::XmlElement("Envelope", $NS); if ($context) { my $header= new Zimbra::SOAP::XmlElement("Header", $NS); $header->add_child($context); $env->add_child($header); } my $body = new Zimbra::SOAP::XmlElement("Body", $NS); $body->add_child($e); $env->add_child($body); return $env; } sub getContentType() { return "text/xml; charset=utf-8" } # # Return the namespace String # sub getNamespace { return $NS; } # # return the first child in the soap body # sub getElement { my ($self, $e) = @_; die "getElement was not passed a Soap Envelope" unless ($e->name() eq 'Envelope') && ($e->ns() eq $NS); my $body = $e->find_child('Body'); die "getElement unable to find Soap Body" unless defined $body; return $body->child(0); } # # Returns true if this element represents a SOAP fault # sub isFault { my ($self, $e) = @_; return ($e->name() eq 'Fault') && ($e->ns() eq $NS); } # # Whether or not to include a HTTP SOAPActionHeader. (Gag) # sub hasSOAPActionHeader { return 1; } # # returns the version as a string (e.g, "1.1" or "1.2") # sub getVersion { return "1.1"; } 1; ================================================ FILE: lib/Zimbra/SOAP/Soap12.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package Zimbra::SOAP::Soap12; use strict; use warnings; use XML::Parser; use Zimbra::SOAP::XmlElement; #use overload '""' => \&to_string; BEGIN { use Exporter (); our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); # set the version for version checking $VERSION = 1.00; @ISA = qw(Exporter Zimbra::SOAP::Soap); @EXPORT = qw(); %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], # your exported package globals go here, # as well as any optionally exported functions @EXPORT_OK = qw(); } our @EXPORT_OK; our $NS = "http://www.w3.org/2003/05/soap-envelope"; sub new { my $type = shift; my $self = {}; bless $self, $type; return $self; } # # given a XmlElement, wrap it in a SOAP envelope and return the envelope # sub soapEnvelope { my $self = shift; my $e = shift; my $context = shift; my $env = new Zimbra::SOAP::XmlElement("Envelope", $NS); if ($context) { my $header= new Zimbra::SOAP::XmlElement("Header", $NS); $header->add_child($context); $env->add_child($header); } my $body = new Zimbra::SOAP::XmlElement("Body", $NS); $body->add_child($e); $env->add_child($body); return $env; } sub getContentType() { return "application/soap+xml; charset=utf-8"; } # # Return the namespace String # sub getNamespace { return $NS; } # # return the first child in the soap body # sub getElement { my ($self, $e) = @_; die "getElement was not passed a Soap Envelope" unless ($e->name() eq 'Envelope') && ($e->ns() eq $NS); my $body = $e->find_child('Body'); die "getElement unable to find Soap Body" unless defined $body; return $body->child(0); } # # Returns true if this element represents a SOAP fault # sub isFault { my ($self, $e) = @_; return ($e->name() eq 'Fault') && ($e->ns() eq $NS); } # # Whether or not to include a HTTP SOAPActionHeader. (Gag) # sub hasSOAPActionHeader { return 0; } # # returns the version as a string (e.g, "1.1" or "1.2") # sub getVersion { return "1.2"; } 1; ================================================ FILE: lib/Zimbra/SOAP/XmlDoc.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package Zimbra::SOAP::XmlDoc; use strict; use warnings; use Zimbra::SOAP::XmlElement; BEGIN { use Exporter (); our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); # set the version for version checking $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw(); %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], # your exported package globals go here, # as well as any optionally exported functions @EXPORT_OK = qw(); } our @EXPORT_OK; sub new { my $type = shift; my $self = {}; bless $self, $type; return $self; } sub to_string { my $self = shift; return $self->{'root'}->to_string(@_); } sub start { my $self = shift; my $name = shift; my $ns = shift; my $element = new Zimbra::SOAP::XmlElement($name, $ns); if (@_) { my $attrs = shift; $element->attrs($attrs) if defined($attrs); } if (@_) { $element->content(shift); } if (!defined($self->{'root'})) { $self->{'root'} = $element; } else { my $s = $self->{'stack'}; my $parent = @{$s}[$#{$s}]; $parent->add_child($element); } push(@{$self->{'stack'}}, $element); return $self; } sub current { my $self = shift; my $s = $self->{'stack'}; my $e = @{$s}[$#{$s}] || die "not in an element"; return $e; } sub end { my $self = shift; my $s = $self->{'stack'}; my $e = @{$s}[$#{$s}] || die "not in an element"; if (@_) { my $name = shift; my $aname = $e->name; if ($name ne $aname) { die "name mismatch in end. expecting($name), actual($aname)"; } } pop(@{$self->{'stack'}}); } sub add { my ($self, $name, $ns, $attrs, $text) = @_; $self->start($name, $ns, $attrs); $self->current->append_content($text) if defined($text); $self->end; } sub root { my $self = shift; return $self->{'root'}; } 1; __END__ ================================================ FILE: lib/Zimbra/SOAP/XmlElement.pm ================================================ # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package Zimbra::SOAP::XmlElement; use strict; use warnings; use XML::Parser; #use overload '""' => \&to_string; BEGIN { use Exporter (); our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); # set the version for version checking $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT = qw(); %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ], # your exported package globals go here, # as well as any optionally exported functions @EXPORT_OK = qw(); } our @EXPORT_OK; # # parses XML into a hash of hashes, where 'name' is the name # of the tag, 'ns' is the namespace URI, # 'attrs' is a hash of the attributes, 'children' # is an array of the child elements, and 'content' is all of # the textual content. # # for example: # # # # {base64-krb5-mk-req-data} # # # # # # # will parse into: # # $tree = { # 'name' => 'getTokensRequest', # 'ns' => 'http://stanford.edu/wkdc', # 'attrs' => {}, # 'children' => [ # { # 'name' => 'requesterCredential', # 'attrs' => { 'type' => 'krb5' }, # 'content' => ' {base64-krb5-mk-req-data} ' # }, # { # 'name' => 'tokens', # 'attrs' => {}, # 'children' => [ # { # 'name' => 'token', # 'attrs' => { 'id' => 0, 'type' => 'service'}, # 'content' => ' ' # } # ] # } # ] # 'content' => ' ' # }; # # note that all the whitespace in the document will get left # in. It should be trim'd if needed. # sub parse { my $xml = shift; my $parser = new XML::Parser(Namespaces => 1, Handlers => { Start => \&XPStart, End => \&XPEnd, Char => \&XPChar, Init => \&XPInit, Final => \&XPFinal }); return $parser->parse($xml); } # creates a new element with the specified name and namespace sub new { my $type = shift; my ($name, $ns) = @_; my $self = { 'attrs' => {}, 'children' => []}; bless $self, $type; $self->name($name) if defined $name; $self->ns($ns) if defined $ns; return $self; } # returns the name of this element sub name { my $self = shift; $self->{'name'} = shift if @_; return $self->{'name'}; } # returns the URI of the namespace of this element sub ns { my $self = shift; $self->{'ns'} = shift if @_; return $self->{'ns'}; } # returns the content sub content { my $self = shift; $self->{'content'} = shift if @_; return $self->{'content'}; } # returns the content with leading and trailing whitespace removed sub content_trimmed { my $self = shift; my $c = $self->{'content'}; $c =~ s/^\s*(.*)\s*$/$1/; return $c; } # apppend the given string to the content sub append_content { my $self = shift; $self->{'content'} .= shift if @_; } # returns (and sets new if specified) the hash ref containing attrs sub attrs { my $self = shift; $self->{'attrs'} = shift if @_; return $self->{'attrs'}; } # returns true if this element has any attrs sub has_attrs { my $self = shift; return %{$self->{'attrs'}}; } # returns (and sets new if specified) attribute sub attr { my $self = shift; my $name = shift; $self->{'attrs'}{$name} = shift if @_; return $self->{'attrs'}{$name}; } # returns (and sets new if specified) child array ref sub children { my $self = shift; $self->{'children'} = shift if @_; return $self->{'children'}; } # returns true if this element has any children sub has_children { my $self = shift; return $#{$self->{'children'}} != -1; } # returns the number of children sub num_children { my $self = shift; return $#{$self->{'children'}} + 1; } # return the child at the specified index sub child { my ($self, $index) = @_; return $self->{'children'}->[$index]; } # this will only find the first child with the given name sub find_child { my $self = shift; my $name = shift; foreach my $child (@{$self->children}) { return $child if ($child->name() eq $name); } return undef; } # add a new child sub add_child { my $self = shift; push @{$self->{'children'}}, shift; } # escape any special XML characters sub escape { my $v = shift; $$v =~ s/&/&/sg; $$v =~ s//>/sg; $$v =~ s/\"/"/sg; $$v =~ s/\'/'/sg; } sub recursive_to_string { my ($e, $ctxt) = @_; my $pretty = $ctxt->{'pretty'}; my $level = $ctxt->{'level'}; my $out = $ctxt->{'out'}; my $name = $e->name(); my $ns_uri = $e->ns(); my $xmlns; if (defined $ns_uri) { my $prefix = get_ns_prefix($ctxt, $ns_uri); if (!defined($prefix)) { $prefix = new_ns_prefix($ctxt, $ns_uri); $xmlns = "xmlns:$prefix=\"$ns_uri\""; } $name = "$prefix:$name"; } my $closed = 0; my $cont = 0; $$out .= ' ' x $level if $pretty; $$out .= "<$name"; while (my($attr,$val) = each(%{$e->attrs})) { escape(\$val); $$out .= " $attr=\"$val\""; } $$out .= " $xmlns" if $xmlns; my $child; if (defined($e->content)) { if (!$closed) { $$out .= ">"; $closed=1; } $cont = 1; my $c = $e->content; escape(\$c); $$out .= $c; } foreach $child (@{$e->children}) { if (!$closed) { $$out .= ">"; $$out .= "\n" if $pretty; $closed=1; } $ctxt->{'level'} += 2; recursive_to_string($child, $ctxt); $ctxt->{'level'} = $level; } if ($closed) { $$out .= ' ' x $level if $pretty && !$cont; $$out .= ""; $$out .= "\n" if $pretty; } else { $$out .= "/>"; $$out .= "\n" if $pretty; } } # returns the prefix of the specified URI sub get_ns_prefix { my ($ctxt, $uri) = @_; my $pre = $ctxt->{'ns'}->{$uri}; return $pre; } # create a new prefix for the specified URI sub new_ns_prefix { my ($ctxt, $uri) = @_; chomp $uri if ($uri =~ m!/$!); #my ($pre) = ($uri =~ m!.*/([a-zA-z][a-zA-Z0-9]{1,4})!); #if (defined $ctxt->{$pre}) { my $pre = "ns" . $ctxt->{'nscounter'}++; #} else { #$ctxt->{$pre} = 1; #} $ctxt->{'ns'}->{$uri} = $pre; return $pre; } # convert this element to a string sub to_string { my $self = shift; my $pretty = shift; my $output = ""; my $ctxt = {pretty => $pretty, out => \$output, level => 0, nscounter => 0, ns => {} }; recursive_to_string($self, $ctxt); return $output; } # XML::Parser Init handler sub XPInit { my $expat = shift; $expat->{'Doc'} = {}; $expat->{'Stack'} = []; $expat->{'Cur'} = undef; } # XML::Parser Start handler sub XPStart { my $expat = shift; my $tag = shift; my $element = new Zimbra::SOAP::XmlElement($tag, $expat->namespace($tag)); if ($#_ >= 0) { $element->attrs({@_}); } my $cur = $expat->{'Cur'}; if (defined $cur) { $cur->add_child($element); push @{$expat->{'Stack'}}, $cur; } else { $expat->{'Doc'} = $element; } $expat->{'Cur'} = $element; } # XML::Parser End handler sub XPEnd { my $expat = shift; my $tag = shift; $expat->{'Cur'} = pop @{ $expat->{'Stack'}}; } # XML::Parser Char handler sub XPChar { my $expat = shift; my $text = shift; my $e = $expat->{'Cur'}; $e->append_content($text); } # XML::Parser Final handler sub XPFinal { my $expat = shift; delete $expat->{'Cur'}; delete $expat->{'Stack'}; $expat->{'Doc'}; } 1; ================================================ FILE: lib/Zimbra/Util/Common.pm ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2006, 2007, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** package Zimbra::Util::Common; use strict; # Zimbra Specfic library locations use lib "/opt/zimbra/common/lib/perl5"; use lib "/opt/zimbra/common/lib/perl5/Zimbra/SOAP"; use lib "/opt/zimbra/common/lib/perl5/Zimbra/Mon"; use lib "/opt/zimbra/common/lib/perl5/Zimbra/DB"; foreach my $arch (qw(i386 x86_64 i486 i586 i686 darwin)) { foreach my $type (qw(linux-thread-multi linux-gnu-thread-multi linux thread-multi thread-multi-2level)) { my $dir = "/opt/zimbra/common/lib/perl5/${arch}-${type}"; unshift(@INC, "$dir") if (-d "$dir"); } } 1 ================================================ FILE: lib/Zimbra/Util/LDAP.pm ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** package Zimbra::Util::LDAP; use strict; use Net::LDAP; sub doLdap() { my $self=shift; my ($key, $value) = @_; my $is_master = $main::config{ldap_is_master}; my $pw = $main::config{ldap_root_password}; my $rc=0; my $real_master=0; my ($dn,$ldap_key); my $ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/') or die "$@"; my $mesg = $ldap->bind("cn=config", password=>"$pw"); if($mesg->code) { main::logMsg(2,"LDAP: Failed to bind"); $ldap->unbind; return 1; } if (lc($is_master) eq "true") { $mesg = $ldap->search( base=> "cn=accesslog", filter=>"(objectClass=*)", scope => "base", attrs => ['1.1'], ); my @entries=$mesg->entries; my $size = @entries; if ($size > 0 ) { $real_master = 1; } } if ($key =~ /^ldap_common_/) { if ($key eq "ldap_common_loglevel") { $ldap_key="olcLogLevel"; } elsif ($key eq "ldap_common_threads") { $ldap_key="olcThreads"; } elsif ($key eq "ldap_common_toolthreads") { $ldap_key="olcToolThreads"; } elsif ($key eq "ldap_common_require_tls") { $ldap_key="olcSecurity"; chomp($value); $value="ssf=$value"; } elsif ($key eq "ldap_common_writetimeout") { $ldap_key="olcWriteTimeout"; } else { main::logMsg(2,"LDAP common: Unknown key: $key"); $rc=1; } $dn="cn=config"; } elsif ($key =~ /^ldap_db_/) { if ($real_master) { $dn="olcDatabase={3}mdb,cn=config"; } else { $dn="olcDatabase={2}mdb,cn=config"; } if ($key eq "ldap_db_checkpoint") { $ldap_key="olcDbCheckpoint"; } elsif ($key eq "ldap_db_maxsize") { $ldap_key="olcDbMaxsize"; } else { main::logMsg(2,"LDAP db: Unknown key: $key"); $rc=1; } } elsif ($key =~ /ldap_access/) { if ($real_master) { $dn="olcDatabase={2}mdb,cn=config"; if ($key eq "ldap_accesslog_checkpoint") { $ldap_key="olcDbCheckpoint"; } elsif ($key eq "ldap_accesslog_maxsize") { $ldap_key="olcDbMaxsize"; } else { main::logMsg(2,"LDAP accesslog: Unknown key: $key"); $rc=1; } } } elsif ($key =~ /ldap_overlay/) { if ($real_master) { if ($key =~ /ldap_overlay_syncprov/) { $dn="olcOverlay={0}syncprov,olcDatabase={3}mdb,cn=config"; if ($key eq "ldap_overlay_syncprov_checkpoint") { $ldap_key="olcSpCheckpoint"; } else { main::logMsg(2,"LDAP overlay syncprov: Unknown key: $key"); $rc=1; } } elsif ($key =~ /ldap_overlay_accesslog/) { $dn="olcOverlay={1}accesslog,olcDatabase={3}mdb,cn=config"; if ($key eq "ldap_overlay_accesslog_logpurge") { $ldap_key="olcAccessLogPurge"; } else { main::logMsg(2,"LDAP overlay accesslog: Unknown key: $key"); $rc=1; } } else { main::logMsg(2,"LDAP overlay: Unknown key: $key"); $rc=1; } } } else { main::logMsg(2,"LDAP: Unknown key: $key"); $rc=1; } if ($rc) { $ldap->unbind; return $rc; } if (!$real_master && ($key =~ /ldap_access/ || $key =~ /ldap_overlay/)) { main::logMsg(2,"LDAP: Trying to modify key: $key when not a master"); $ldap->unbind; return 0; } my $entry; if ($real_master && $key =~ /ldap_overlay_syncprov/) { # Obtain real syncprov overlay DN $mesg=$ldap->search(base=>"olcDatabase={3}mdb,cn=config", scope=>"sub", filter=>'(objectClass=olcSyncProvConfig)', attrs=>[ "1.1" ], ); $entry=$mesg->entry(0); $dn=$entry->dn(); } if ($real_master && $key =~ /ldap_overlay_accesslog/) { # Obtain real syncprov overlay DN $mesg=$ldap->search(base=>"olcDatabase={3}mdb,cn=config", scope=>"sub", filter=>'(objectClass=olcAccessLogConfig)', attrs=>[ "1.1" ], ); $entry=$mesg->entry(0); $dn=$entry->dn(); } $mesg=$ldap->search(base=>$dn, scope=>"base", filter=>'objectClass=*', attrs=>[ "$ldap_key" ], ); $entry=$mesg->entry(0); my $orig_value = $entry->get_value("$ldap_key"); if ($orig_value ne $value) { main::logMsg(3,"LDAP: Changing key: $key"); $mesg = $ldap->modify( $dn, replace=>{$ldap_key=>"$value"}, ); if ($mesg->code) { main::logMsg(2,"LDAP key change failed: ".$mesg->code()); $rc=1; } } $ldap->unbind; return $rc; } 1; ================================================ FILE: lib/Zimbra/Util/Timezone.pm ================================================ package Zimbra::Util::Timezone; use strict; our %TIMEZONES; our $_PARSED=0; sub new { my $class = shift; my $tzname = shift; my $self = { tzname => $tzname, tzid=>undef, primary=>undef }; bless $self, $class; $TIMEZONES{$self} = $self; } sub tzname { my $self = shift; if (@_) { $self->{tzname} = shift; } else { $self->{tzname}; } } sub tzid { my $self = shift; if (@_) { $self->{tzid} = shift; } else { $self->{tzid}; } } sub tzalias { my $self = shift; if (@_) { $self->{tzalias} = shift if ($self->{tzalias} eq ""); } else { $self->{tzalias}; } } sub primary { my $self = shift; if (@_) { $self->{primary} = shift; } else { $self->{primary}; } } sub parse { my $self = shift; my $file = shift; return if ($_PARSED == 1); $file="/opt/zimbra/conf/timezones.ics" if ($file eq ""); open(FILE, "$file") or return undef; my $tz; while () { $tz = $self->new if (/BEGIN:VTIMEZONE/); $tz->tzid($1) if (/TZID:(.+)/); $tz->tzname($1) if (/TZNAME:(.+)/); $tz->primary(1) if (/X-ZIMBRA-TZ-PRIMARY:TRUE/); next if (/END:VTIMEZONE/); } close(FILE); $_PARSED=1; return $tz; } sub gettzbyname { my $self = shift; my $name = shift; foreach (sort values %TIMEZONES) { return $_ if ($_->tzname eq $name && $_->primary == 1); } return undef; } sub gettzbyid { my $self = shift; my $name = shift; foreach (sort values %TIMEZONES) { return $_ if ($_->tzid eq $name && $_->primary == 1); } return undef; } sub dump { my $self = shift; my @tzs; foreach (values %TIMEZONES) { #next if ($_->tzname eq ""); push(@tzs, $_->tzid) if ($_->primary == 1); } return @tzs; } 1; ================================================ FILE: lib/Zimbra/ZmClient.pm ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2010, 2012, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package ZmClient; use IPC::Open2; use POSIX ":sys_wait_h"; use IO::Handle; use Net::HTTP; use LWP::UserAgent; use HTTP::Request; $SIG{CHLD} = 'IGNORE'; # PvZ ftw my $zmprov_exe = '/opt/zimbra/bin/zmprov'; my %zmprov = (); my %zmprovl = (); my $zmmailbox_exe = '/opt/zimbra/bin/zmmailbox'; my %zmmailbox = (); my %authTokens = (); sub init() { $zmprov_exe = '/opt/zimbra/bin/zmprov'; %zmprov = (); $zmmailbox_exe = '/opt/zimbra/bin/zmmailbox'; %zmmailbox = (); %authTokens = (); } sub initZmprovSoap() { my $buf; return if (exists $zmprov{'pid'} && kill(0, $zmprov{'pid'})); $zmprov{'pid'} = open2( $zmprov{'in'}, $zmprov{'out'}, "$zmprov_exe 2>&1 ") || die "$!"; eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm(60); # avoid timeouts when mailstore is down do { # this part, we can ignore sysread($zmprov{'in'}, $buf, 8192); } while ($buf !~ /^prov> $/osm); alarm(0); }; } sub initZmprovLdap() { my $buf; return if (exists $zmprovl{'pid'} && kill(0, $zmprovl{'pid'})); $zmprovl{'pid'} = open2( $zmprovl{'in'}, $zmprovl{'out'}, "$zmprov_exe -l 2>&1 ") || die "$!"; eval { local $SIG{ALRM} = sub { die "alarm\n" }; alarm(60); # avoid timeouts when ldap is down do { # this part, we can ignore sysread($zmprovl{'in'}, $buf, 8192); } while ($buf !~ /^prov> $/osm); alarm(0); }; } sub initZmprov() { initZmprovSoap(); initZmprovLdap(); } sub sendZmprovRequestSoap($) { my $cmd = shift @_; my $buf; initZmprovSoap unless (exists $zmprov{'pid'} && kill(0, $zmprov{'pid'})); die "zmprov not initialized" if (!exists $zmprov{'out'}); $zmprov{'out'}->print($cmd . "\n"); my @lines = (); my $needs_join = 0; do { sysread($zmprov{'in'}, $buf, 8192); my @newlines = split(/\n/, $buf); if ($needs_join) { $lines[$#lines] .= shift @newlines if @newlines > 0; $needs_join = 0; } $needs_join = 1 if ($buf !~ /\n$/osm); push(@lines, @newlines); } while ($buf !~ /^prov> $/osm); pop @lines if ($lines[$#lines] =~ /^prov> $/osm); wantarray ? @lines : join("\n", @lines); } sub sendZmprovRequestLdap($) { my $cmd = shift @_; my $buf; initZmprovLdap unless (exists $zmprovl{'pid'} && kill(0, $zmprovl{'pid'})); die "zmprovl not initialized" if (!exists $zmprovl{'out'}); $zmprovl{'out'}->print($cmd . "\n"); my @lines = (); my $needs_join = 0; do { sysread($zmprovl{'in'}, $buf, 8192); my @newlines = split(/\n/, $buf); if ($needs_join) { $lines[$#lines] .= shift @newlines if @newlines > 0; $needs_join = 0; } $needs_join = 1 if ($buf !~ /\n$/osm); push(@lines, @newlines); } while ($buf !~ /^prov> $/osm); pop @lines if ($lines[$#lines] =~ /^prov> $/osm); wantarray ? @lines : join("\n", @lines); } sub sendZmprovRequest($) { waitpid (-1, WNOHANG); my $cmd = shift @_; my @lines; if ($cmd =~ m/^-l\s+/) { $cmd =~ s/^-l\s+//; @lines = sendZmprovRequestLdap($cmd); } else { @lines = sendZmprovRequestSoap($cmd); } wantarray ? @lines : join("\n", @lines); } 1; ================================================ FILE: rpmconf/Build/checkLicense.pl ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # use strict; use lib qw(/opt/zimbra/common/lib/perl5 /opt/zimbra/zimbramon/lib); use LWP::UserAgent; use Getopt::Long; use Net::LDAP; use XML::Simple; sub valid_licensekey { my ($licensekey) = @_; return $licensekey =~ /^[A-Za-z0-9]{18,24}$/; } sub set_permissions { my ($file) = @_; system("chown zimbra:zimbra $file"); system("chmod 644 $file"); } sub compare_versions { my ($version1, $version2) = @_; my @v1 = split /\./, $version1; my @v2 = split /\./, $version2; for my $i (0 .. $#v1) { return -1 if !defined $v2[$i]; return 1 if $v1[$i] > $v2[$i]; return -1 if $v1[$i] < $v2[$i]; } return 0 if @v1 == @v2; return 1 if @v1 > @v2; return -1; } my %options; my ( $licensekey, $blah, $host ); GetOptions( \%options, "upgradeVersion|uv=s", "currentVersion|cv=s", "internal", "help" ) or usage(); sub usage { print( "usage: checkLicense.pl -uv UPGRADEVERSION -cv CURRENTVERSION [-i]\n", "\t-uv UPGRADEVERSION: Example: -uv 8.7.0\n", "\t-cv CURRENTVERSION: Example: -cv 8.6.0\n", "\t-i: Internal Zimbra usage\n", "\t-h: Display this help message\n" ); exit(0); } if ( $options{help} ) { usage(); } if ( $options{internal} ) { $host = 'http://zimbra-stage-license.eng.zimbra.com'; } else { $host = 'https://license.zimbra.com'; } unless ( $options{upgradeVersion} && $options{currentVersion} ) { myDie(3,"ERROR: Both upgrade version and current version must be supplied.\n"); } my $localxml = XMLin("/opt/zimbra/conf/localconfig.xml"); my $ldap_master_url = $localxml->{key}->{ldap_master_url}->{value}; my $master_ref = [ split( " ", $ldap_master_url ) ]; my $zimbra_admin_dn = $localxml->{key}->{zimbra_ldap_userdn}->{value}; my $zimbra_admin_password = $localxml->{key}->{zimbra_ldap_password}->{value}; chomp($zimbra_admin_password); my $ldap_starttls_supported = $localxml->{key}->{ldap_starttls_supported}->{value}; my $zimbra_require_interprocess_security = $localxml->{key}->{zimbra_require_interprocess_security}->{value}; my $ldap = Net::LDAP->new($master_ref) or myDie(4,"Error connecting to LDAP server: $ldap_master_url\n"); my $mesg; if ( $ldap_master_url !~ /^ldaps/i ) { if ($ldap_starttls_supported) { $mesg = $ldap->start_tls( verify => 'none', capath => "/opt/zimbra/conf/ca", ) or myDie(5,"start_tls: $@\n"); $mesg->code && myDie(5,"TLS: ", $mesg->error, "\n"); } } $mesg = $ldap->bind( "$zimbra_admin_dn", password => "$zimbra_admin_password" ); $mesg->code && myDie(6,"Bind: ", $mesg->error, "\n"); $mesg = $ldap->search( base => "cn=config,cn=zimbra", filter => "(zimbraNetworkRealtimeLicense=*)", scope => "base", attrs => [ 'zimbraNetworkRealtimeLicense'], ); my $size = $mesg->count; if (compare_versions($options{currentVersion}, '10.1.0') >= 0 && $size == 0) { $ldap->unbind(); myDie(2,"Error: License key not detected\n"); } my $entry = $mesg->entry(0); my $licensekey = ""; if ($entry) { $licensekey = $entry->get_value("zimbraNetworkRealtimeLicense"); } if (!defined($licensekey) || $licensekey eq '') { my $license_file = "/opt/zimbra/conf/ZCSLicensekey"; if (-e $license_file) { chomp($licensekey = qx(cat $license_file)); } else { print "\n"; print "Please enter the license key (an alphanumeric string of 18-24 characters without any special characters):"; $licensekey = ; chomp($licensekey); if (!valid_licensekey($licensekey)) { myDie(7,"Error: Invalid license key entered \n"); } system("echo \"$licensekey\" > $license_file"); set_permissions($license_file); } } my $caf = '/opt/zimbra/zimbramon/lib/Mozilla/CA/cacert.pem'; my @lwpargs = -f $caf ? ( ssl_opts => { SSL_ca_file => $caf, SSL_ca_path => undef } ) : (); my $browser = LWP::UserAgent->new(@lwpargs); $browser->env_proxy; my $request = HTTP::Request->new(POST => "$host/rest/v1/public/license/$licensekey/validate?version=$options{upgradeVersion}"); $request->header('Content-Type' => 'application/json'); my $response = $browser->request($request); if ( $response->is_success ) { my $json_content = $response->content; my ($status_code) = $json_content =~ /"status":\s*(\d+)/; if (defined $status_code && $status_code == 2000) { my ($status_message) = $json_content =~ /"statusMessage":\s*"([^"]*)"/; myDie(0, "SUCCESS: ", $status_message, "\n"); } else { myDie(1, "ERROR: ", $response->content, "\n"); } } else { myDie(1, "ERROR: ", $response->content, "\n"); } sub myDie() { my ($rc, @msg) = @_; if (@msg) { if ($rc != 0) { warn (@msg); } else { print STDOUT @msg; } } exit ($rc); } ================================================ FILE: rpmconf/Build/checkService.pl ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # use strict; use lib qw(/opt/zimbra/common/lib/perl5 /opt/zimbra/zimbramon/lib); use Getopt::Long; use Net::LDAP; use XML::Simple; my %options; GetOptions( \%options, "service=s", "help" ) or usage(); sub usage { print( "usage: checkService.pl -s SERVICE\n", "\t-s SERVICE: Example: -s proxy\n", ); exit(0); } if ( $options{help} ) { usage(); } unless ( $options{service} ) { die("ERROR: No service supplied.\n"); } my $localxml = XMLin("/opt/zimbra/conf/localconfig.xml"); my $ldap_master_url = $localxml->{key}->{ldap_master_url}->{value}; my $master_ref = [ split( " ", $ldap_master_url ) ]; my $zimbra_admin_dn = $localxml->{key}->{zimbra_ldap_userdn}->{value}; my $zimbra_admin_password = $localxml->{key}->{zimbra_ldap_password}->{value}; chomp($zimbra_admin_password); my $ldap_starttls_supported = $localxml->{key}->{ldap_starttls_supported}->{value}; my $zimbra_require_interprocess_security = $localxml->{key}->{zimbra_require_interprocess_security}->{value}; my $ldap = Net::LDAP->new($master_ref) or die "Error connecting to LDAP server: $ldap_master_url"; my $mesg; my $global_mesg; if ( $ldap_master_url !~ /^ldaps/i ) { if ($ldap_starttls_supported) { $mesg = $ldap->start_tls( verify => 'none', capath => "/opt/zimbra/conf/ca", ) or die "start_tls: $@"; $mesg->code && die "TLS: " . $mesg->error . "\n"; } } $mesg = $ldap->bind( "$zimbra_admin_dn", password => "$zimbra_admin_password" ); $mesg->code && die "Bind: " . $mesg->error . "\n"; $mesg = $ldap->search( base => "cn=servers,cn=zimbra", filter => "(zimbraServiceEnabled=$options{service})", attrs => [ 'zimbraServiceEnabled', 'zimbraReverseProxyMailEnabled', 'zimbraReverseProxyHttpEnabled' ], ); my $size = $mesg->count; my $found_http_proxy_true=0; my $found_mail_proxy_true=0; my $found_http_proxy_false=0; my $found_mail_proxy_false=0; my $total_servers; if ( $size == 0 ) { $ldap->unbind(); print STDERR "Error: $options{service} not enabled\n"; exit 2; } else { if ( $options{service} eq "proxy" ) { $global_mesg = $ldap->bind( "$zimbra_admin_dn", password => "$zimbra_admin_password" ); $global_mesg->code && die "Bind: " . $global_mesg->error . "\n"; $global_mesg = $ldap->search( base => "cn=config,cn=zimbra", filter => "(|(zimbraReverseProxyMailEnabled=TRUE)(zimbraReverseProxyHttpEnabled=TRUE))", attrs => [ 'zimbraReverseProxyMailEnabled', 'zimbraReverseProxyHttpEnabled' ], ); # get globalconfig values of zimbraReverseProxyMailEnabled and zimbraReverseProxyHttpEnabled my $global_size = $global_mesg->count; my $global_zimbraReverseProxyMailEnabled; my $global_zimbraReverseProxyHttpEnabled; if ($global_size != 0) { foreach my $global_entry ( $global_mesg->entries ) { $global_zimbraReverseProxyMailEnabled=$global_entry->get_value("zimbraReverseProxyMailEnabled"); $global_zimbraReverseProxyHttpEnabled=$global_entry->get_value("zimbraReverseProxyHttpEnabled"); } } foreach my $entry ( $mesg->entries ) { $total_servers++; if ( $entry->get_value("zimbraReverseProxyMailEnabled") eq "TRUE" ) { $found_mail_proxy_true++; } if ( $entry->get_value("zimbraReverseProxyMailEnabled") eq "FALSE" ) { $found_mail_proxy_false++; } if ( $entry->get_value("zimbraReverseProxyHttpEnabled") eq "TRUE" ) { $found_http_proxy_true++; } if ( $entry->get_value("zimbraReverseProxyHttpEnabled") eq "FALSE" ) { $found_http_proxy_false++; } } if ((($found_mail_proxy_true < 1 && $global_zimbraReverseProxyMailEnabled eq "FALSE") && ($found_http_proxy_true < 1 && $global_zimbraReverseProxyHttpEnabled eq "FALSE")) || (($found_http_proxy_false eq $total_servers) || ($found_mail_proxy_false eq $total_servers))){ print STDERR "Error: One or more proxies do not have zimbraReverseProxyMailEnabled and zimbraReverseProxyHttpEnabled set to TRUE. \nIt is required to have at least one proxy with zimbraReverseProxyMailEnabled and at least one proxy with zimbraReverseProxyHttpEnabled for ZCS 8.7+\n"; exit 3; } } } ================================================ FILE: rpmconf/Build/create_distribution.dist.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # PKGDIR=$1 TEMPLATE=$2 get_size_from_pkg() { pkg=$1 bpkg=`basename $pkg` NAME=`echo $bpkg | awk -F. '{print $1}'| sed -e 's/zimbra-//' -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` SIZE=`cat ${pkg}/Contents/Info.plist | sed -ne '/IFPkgFlagInstalledSize/{n;p;}'| sed -ne '/integer/ s///p' | sed -e 's/<\/integer>//' -e 's/ //g' -e 's/ //g'` } get_build_num() { DIR=`dirname $0` MAJOR=`cat $DIR/../../RE/MAJOR` MINOR=`cat $DIR/../../RE/MINOR` MICRO=`cat $DIR/../../RE/MICRO` BUILDNUM=`cat $DIR/../../RE/BUILD` } get_build_num for i in ${PKGDIR}/*.pkg; do get_size_from_pkg $i VAR=${NAME}SIZE eval $VAR=$SIZE done cat $TEMPLATE | sed -e "s/@@CORESIZE@@/$CORESIZE/g" \ -e "s/@@LDAPSIZE@@/$LDAPSIZE/g" \ -e "s/@@LOGGERSIZE@@/$LOGGERSIZE/g" \ -e "s/@@ARCHIVINGSIZE@@/$ARCHIVINGSIZE/g" \ -e "s/@@APACHESIZE@@/$APACHESIZE/g" \ -e "s/@@STORESIZE@@/$STORESIZE/g" \ -e "s/@@CONVERTDSIZE@@/$CONVERTDSIZE/g" \ -e "s/@@MEMCACHEDSIZE@@/$MEMCACHEDSIZE/g" \ -e "s/@@MTASIZE@@/$MTASIZE/g" \ -e "s/@@PROXYSIZE@@/$PROXYSIZE/g" \ -e "s/@@SNMPSIZE@@/$SNMPSIZE/g" \ -e "s/@@SPELLSIZE@@/$SPELLSIZE/g" \ -e "s/@@MAJOR@@/$MAJOR/g" \ -e "s/@@MINOR@@/$MINOR/g" \ -e "s/@@MICRO@@/$MICRO/g" \ -e "s/@@BUILDNUM@@/$BUILDNUM/g" ================================================ FILE: rpmconf/Build/get_plat_tag.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # if [ -f /etc/redhat-release ]; then i=`uname -i` if [[ "x$i" == "xx86_64" ]] || [[ "x$i" == "xppc64"* ]]; then i="_64" else i="" fi grep "Red Hat Enterprise Linux.*release 9" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL9${i}" exit 0 fi grep "Red Hat Enterprise Linux.*release 8" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL8${i}" exit 0 fi grep "Red Hat Enterprise Linux.*release 7" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL7${i}" exit 0 fi grep "Red Hat Enterprise Linux.*release 6" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL6${i}" exit 0 fi grep "CentOS Linux release 9" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL9${i}" exit 0 fi grep "CentOS Linux release 8" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL8${i}" exit 0 fi grep "CentOS Linux release 7" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL7${i}" exit 0 fi grep "CentOS release 6" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL6${i}" exit 0 fi grep "Rocky Linux release 9" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL9${i}" exit 0 fi grep "Rocky Linux release 8" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL8${i}" exit 0 fi grep "Scientific Linux release 9" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL9${i}" exit 0 fi grep "Scientific Linux release 8" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL8${i}" exit 0 fi grep "Scientific Linux release 7" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL7${i}" exit 0 fi grep "Scientific Linux release 6" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHEL6${i}" exit 0 fi grep "Fedora release 23" /etc/redhat-release >/dev/null 2>&1 if [ $? = 0 ]; then echo "F23${i}" exit 0 fi grep "Fedora release 22" /etc/redhat-release >/dev/null 2>&1 if [ $? = 0 ]; then echo "F22${i}" exit 0 fi grep "Red Hat Enterprise Linux.*release" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RHELUNKNOWN${i}" exit 0 fi grep "CentOS release" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "CentOSUNKNOWN${i}" exit 0 fi grep "Rocky Linux release" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "RockyUNKNOWN${i}" exit 0 fi grep "Fedora Core release" /etc/redhat-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "FCUNKNOWN${i}" exit 0 fi fi if [ -f /etc/SuSE-release ]; then i=`uname -i` if [[ "x$i" == "xx86_64" ]] || [[ "x$i" == "xppc64"* ]]; then i="_64" else i="" fi grep "SUSE Linux Enterprise Server 11" /etc/SuSE-release >/dev/null 2>&1 if [ $? = 0 ]; then echo "SLES11${i}" exit 0 fi grep "SUSE Linux Enterprise Server 10" /etc/SuSE-release >/dev/null 2>&1 if [ $? = 0 ]; then echo "SLES10${i}" exit 0 fi grep "SUSE Linux Enterprise Server" /etc/SuSE-release >/dev/null 2>&1 if [ $? = 0 ]; then echo "SLESUNKNOWN${i}" exit 0 fi grep "openSUSE" /etc/SuSE-release > /dev/null 2>&1 if [ $? = 0 ]; then echo "openSUSEUNKNOWN${i}" exit 0 fi fi if [ -f /etc/lsb-release ]; then LSB="lsb_release" i=`dpkg --print-architecture` if [ "x$i" = "xamd64" ]; then i="_64" else i="" fi RELEASE=$($LSB -s -c) DISTRIBUTOR=$($LSB -s -i) if [ "$DISTRIBUTOR" = "Ubuntu" ]; then echo -n "UBUNTU" if [ "$RELEASE" = "precise" ]; then echo "12${i}" exit 0 fi if [ "$RELEASE" = "trusty" ]; then echo "14${i}" exit 0 fi if [ "$RELEASE" = "xenial" ]; then echo "16${i}" exit 0 fi if [ "$RELEASE" = "bionic" ]; then echo "18${i}" exit 0 fi if [ "$RELEASE" = "focal" ]; then echo "20${i}" exit 0 fi if [ "$RELEASE" = "jammy" ]; then echo "22${i}" exit 0 fi if [ "$RELEASE" = "noble" ]; then echo "24${i}" exit 0 fi echo "UNKNOWN${i}" exit 0 fi if [ "$DISTRIBUTOR" = "Debian" ]; then echo -n "DEBIAN" if [ "$RELEASE" = "wheezy" ]; then echo "7${i}" exit 0 fi if [ "$RELEASE" = "jessie" ]; then echo "8${i}" exit 0 fi if [ "$RELEASE" = "stretch" ]; then echo "9${i}" exit 0 fi echo "UNKNOWN${i}" exit 0 fi if [ "$DISTRIBUTOR" = "Univention" ]; then echo -n "UCS" if [ "$RELEASE" = "Vahr" ]; then echo "4${i}" exit 0 fi echo "UNKNOWN${i}" exit 0 fi fi if [ -f /etc/debian_version ]; then echo "DEBIANUNKNOWN${i}" exit 0 fi if [ -f /etc/mandriva-release ]; then echo "MANDRIVAUNKNOWN" exit 0 fi if [ -f /etc/release ]; then egrep 'Solaris 10.*X86' /etc/release > /dev/null 2>&1 if [ $? = 0 ]; then echo "SOLARISX86" exit 0 fi echo "SOLARISUNKNOWN" fi a=`uname -a | awk '{print $1}'` p=`uname -p` if [ "x$a" = "xDarwin" ]; then v=`sw_vers | grep ^ProductVersion | awk '{print $NF}' | awk -F. '{print $1"."$2}'` if [ "x$v" = "x10.4" ]; then if [ "x$p" = "xi386" ]; then echo "MACOSXx86" exit 0 fi if [ "x$p" = "xpowerpc" ]; then echo "MACOSX" exit 0 fi else if [ "x$p" = "xi386" ]; then p=x86 fi echo "MACOSX${p}_${v}" exit 0 fi fi echo "UNKNOWN${i}" exit 1 ================================================ FILE: rpmconf/Build/zmValidateLdap.pl ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # # Must be run on a system where the ldap_url key is set to contain all of the # replicas, as that is how the script determines what replicas exist. use strict; use lib qw(/opt/zimbra/common/lib/perl5/ /opt/zimbra/zimbramon/lib); use Net::LDAP; use Getopt::Long; my ( %c, %loaded, %options ); $c{zmlocalconfig} = "/opt/zimbra/bin/zmlocalconfig"; my @verargs = qw (vmajor vminor vmicro umajor uminor umicro); my $opts_good = GetOptions( "vmajor=i" => \$options{vmajor}, "vminor=i" => \$options{vminor}, "vmicro=i" => \$options{vmicro}, "umajor=i" => \$options{umajor}, "uminor=i" => \$options{uminor}, "umicro=i" => \$options{umicro}, "ldap" => \$options{l}, ); if ( !$opts_good ) { print "Error: Invalid options.\n"; exit 1; } my $ldap_is_master = getLocalConfig("ldap_is_master"); if ( lc($ldap_is_master) ne "true" ) { foreach my $arg (@verargs) { unless ( defined $options{$arg} ) { print "Error: All of current major.minor.micro and upgrade major.minor.micro must be provided.\n"; exit 1; } } } my $ldap_master = getLocalConfig("ldap_master_url"); my $admin_user = getLocalConfig("zimbra_ldap_userdn"); my $admin_password = getLocalConfig("zimbra_ldap_password"); my $ldap_starttls_supported = getLocalConfig("ldap_starttls_supported"); my $upgradeOK = 1; my ( $mesgp, $entry ); my @masters = split / /, $ldap_master; foreach my $master (@masters) { my $ldapp; chomp($master); if ( $master =~ /^ldaps:/ ) { $ldapp = Net::LDAP->new( $master, verify => 'require', capath => '/opt/zimbra/conf/ca' ); } else { if ( $ldapp = Net::LDAP->new($master) ) { if ($ldap_starttls_supported) { $mesgp = $ldapp->start_tls( verify => 'require', capath => "/opt/zimbra/conf/ca", ); if ( $mesgp->code ) { print "ERROR: Unable to connect via startTLS to master: $master\n"; exit 1; } } } } if ( !defined($ldapp) ) { print "ERROR: No LDAP connection.\n"; exit 1; } if ( lc($ldap_is_master) ne "true" ) { $mesgp = $ldapp->bind( $admin_user, password => $admin_password ); if ( $mesgp->code ) { print "ERROR: Unable to bind as the Zimbra Admin LDAP user.\n"; $ldapp->unbind(); exit 3; } my $ldap_master_host = $ldapp->host(); $mesgp = $ldapp->search( base => "cn=servers,cn=zimbra", filter => "cn=$ldap_master_host", attrs => [ 'zimbraServerVersionMajor', 'zimbraServerVersionMinor', 'zimbraServerVersionMicro', 'zimbraServerVersionType', 'zimbraServerVersionBuild', ] ); if ( $mesgp->code ) { print "Search error: Unable to search master.\n"; exit 4; } my $size = $mesgp->count; if ( $size != 1 ) { print "Size error: Invalid response from ldap master. Please verify cn=$ldap_master_host,cn=servers,cn=zimbra exists in ldap and is a master ldap server.\n"; exit 4; } my ( $lmMajor, $lmMinor, $lmMicro, $lmType ); my $entry = $mesgp->entry(0); chomp( $lmMajor = $entry->get_value('zimbraServerVersionMajor') ); chomp( $lmMinor = $entry->get_value('zimbraServerVersionMinor') ); chomp( $lmMicro = $entry->get_value('zimbraServerVersionMicro') ); if ( $lmMajor eq "" ) { $upgradeOK = 0; $ldapp->unbind; } if ( ( $lmMajor != $options{umajor} ) || ( $lmMinor != $options{uminor} ) || ( $lmMicro != $options{umicro} ) ) { $upgradeOK = 0; $ldapp->unbind; } } } if ( !$upgradeOK ) { print "ERROR: One or more masters have not yet been upgraded. Aborting.\n"; exit 5; } if ( $options{l} ) { if ( -f '/opt/zimbra/data/ldap/mdb/db/data.mdb' || -f '/opt/zimbra/data/ldap/hdb/db/id2entry.bdb' ) { my $ldap_root_password = getLocalConfig("ldap_root_password"); my $ldap; if ( $options{vmajor} < 8 || ( $options{vmajor} == 8 && $options{vminor} == 0 ) ) { $ldap = Net::LDAP->new( 'ldapi://%2fopt%2fzimbra%2fopenldap%2fvar%2frun%2fldapi/') or die "$@"; } else { $ldap = Net::LDAP->new( 'ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/') or die "$@"; } my $mesg = $ldap->bind( "cn=config", password => $ldap_root_password ); if ( $mesg->code ) { print "ERROR: Unable to bind as root LDAP user.\n"; $ldap->unbind(); exit 2; } my $admin_user = getLocalConfig("zimbra_ldap_userdn"); my $admin_password = getLocalConfig("zimbra_ldap_password"); $mesg = $ldap->bind( $admin_user, password => $admin_password ); if ( $mesg->code ) { print "ERROR: Unable to bind as Zimbra Admin LDAP user.\n"; $ldap->unbind(); exit 3; } $ldap->unbind(); } } sub getLocalConfig { my ( $key, $force ) = @_; return $loaded{lc}{$key} if ( exists $loaded{lc}{$key} && !$force ); my $val = qx($c{zmlocalconfig} -x -s -m nokey ${key} 2> /dev/null); chomp($val); $loaded{lc}{$key} = $val; return $val; } ================================================ FILE: rpmconf/Conf/auditswatchrc ================================================ # Failures for an ip:account pair watchfor /\[.*\w+=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3});.*\]\s+.*cmd=.*Auth; account=(.*?);.*error=authentication failed for .*/ exec /bin/echo "IP:Acct failure threshold exceeded: $1 $2" mail addresses=@@zimbra_swatch_notice_user@@,subject="ABUSE: IP:Acct threshold exceeded: $1 $2" threshold track_by=$1:$2,type=both,count=@@zimbra_swatch_ipacct_threshold@@,seconds=@@zimbra_swatch_threshold_seconds@@ continue # Failures for a specific account watchfor /\[.*\w+=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3});.*\]\s+.*cmd=.*Auth; account=(.*?);.*error=authentication failed for .*/ exec /bin/echo "Account failure threshold exceeded: $1 $2" mail addresses=@@zimbra_swatch_notice_user@@,subject="ABUSE: Account threshold exceeded: $1 $2" threshold track_by=$2,type=both,count=@@zimbra_swatch_acct_threshold@@,seconds=@@zimbra_swatch_threshold_seconds@@ continue # Failures from a specific IP watchfor /\[.*\w+=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3});.*\]\s+.*cmd=.*Auth; account=(.*?);.*error=authentication failed for .*/ mail addresses=@@zimbra_swatch_notice_user@@,subject="ABUSE: IP threshold exceeded: $1 $2" exec /bin/echo "IP failure threshold exceeded: $1 exceeded threshold on failure for $2" threshold track_by=$1,type=both,count=@@zimbra_swatch_ip_threshold@@,seconds=@@zimbra_swatch_threshold_seconds@@ continue # All auth failures watchfor /\[.*\w+=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3});.*\]\s+.*cmd=.*Auth; account=(.*?);.*error=authentication failed for .*/ mail addresses=@@zimbra_swatch_notice_user@@,subject="ABUSE: Excessive auth failures detected." exec /bin/echo "Excessive authentication failures detected." threshold track_by=$1,type=both,count=@@zimbra_swatch_total_threshold@@,seconds=@@zimbra_swatch_threshold_seconds@@ continue ================================================ FILE: rpmconf/Conf/hotspot_compiler ================================================ exclude com/zimbra/cs/session/SessionMap.putAndPrune exclude com/zimbra/cs/mailbox/MailItem.delete exclude org/apache/xerces/impl/XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch ================================================ FILE: rpmconf/Conf/logswatchrc ================================================ ignore /DEBUG/ watchfor /.*/ pipe /opt/zimbra/libexec/zmlogger,MESSAGE=$_\n,KEEP_OPEN=1 ================================================ FILE: rpmconf/Conf/mibs/zimbra.mib ================================================ ZIMBRA-MIB DEFINITIONS ::= BEGIN IMPORTS enterprises FROM SNMPv2-SMI; zimbra OBJECT IDENTIFIER ::= { enterprises 666 } zmStatus OBJECT IDENTIFIER ::= { zimbra 1 } zmServiceName OBJECT-TYPE SYNTAX OCTET STRING (SIZE(1..32)) MAX-ACCESS not-accessible STATUS current DESCRIPTION "Service Name" ::= { zmStatus 0 } zmServiceStatus OBJECT-TYPE SYNTAX INTEGER MAX-ACCESS not-accessible STATUS current DESCRIPTION "Service Status" ::= { zmStatus 1 } END ================================================ FILE: rpmconf/Conf/mibs/zimbra_traps.mib ================================================ ZIMBRA-TRAP-MIB DEFINITIONS ::= BEGIN IMPORTS zimbra FROM ZIMBRA-MIB; zmtraps OBJECT IDENTIFIER ::= { zimbra 0 } zmServiceStatusTrap NOTIFICATION-TYPE STATUS current DESCRIPTION "Service Status Change" ::= { zmtraps 0 } END ================================================ FILE: rpmconf/Conf/snmp.conf ================================================ ########################################################################### # # snmp.conf # # - created by the snmpconf configuration program # ########################################################################### # SECTION: Default Authentication Options # # This section defines the default authentication # information. Setting these up properly in your # ~/.snmp/snmp.conf file will greatly reduce the amount of # command line arguments you need to type (especially for snmpv3). # defaultport: The default port number to use # This token specifies the default port number you want packets to # be sent to and received from. # override: with -p on the command line. # arguments: portnum defaultport 162 # defversion: The default snmp version number to use. # override: with -v on the command line. # arguments: 1|2c|3 defversion 2c # defcommunity: The default snmpv1 and snmpv2c community name to use when needed. # If this is specified, you don't need to include the community # name as an argument to the snmp applications. # override: with -c on the command line. # arguments: communityname defcommunity zimbra ########################################################################### # SECTION: Output style options # # This section allows you to control how the output of the # various commands will be formated # logtimestamp: Should timestamps be shown on the output # arguments: (1|yes|true|0|no|false) logtimestamp 1 # printnumericoids: Print OIDs numericly or textually # command line equivelent: -On # arguments: (1|yes|true|0|no|false) printnumericoids 0 ########################################################################### # SECTION: Textual mib parsing # # This section controls the textual mib parser. Textual # mibs are parsed in order to convert OIDs, enumerated # lists, and ... to and from textual representations # and numerical representations. # mibdirs: Specifies directories to be searched for mibs. # Adding a '+' sign to the front of the argument appends the new # directory to the list of directories already being searched. # arguments: [+]directory[:directory...] mibdirs +/opt/zimbra/common/share/snmp/mibs ================================================ FILE: rpmconf/Conf/snmpd.conf.in ================================================ ########################################################################### # # snmpd.conf # # - created by the snmpconf configuration program # ########################################################################### # SECTION: Trap Destinations # # Here we define who the agent will send traps to. # trapsink: A SNMPv1 trap receiver # arguments: host [community] [portnum] trapsink @@SNMPHOST@@ zimbra # trap2sink: A SNMPv2c trap receiver # arguments: host [community] [portnum] trap2sink @@SNMPHOST@@ zimbra # informsink: A SNMPv2c inform (acknowledged trap) receiver # arguments: host [community] [portnum] informsink @@SNMPHOST@@ zimbra # trapcommunity: Default trap sink community to use # arguments: community-string trapcommunity zimbra ================================================ FILE: rpmconf/Conf/swatchrc ================================================ perlcode 0 my %notifications=(); perlcode 0 $notifications{smtp}="@@DOSMTPNOTIFICATIONS@@"; perlcode 0 $notifications{snmp}="@@DOSNMPNOTIFICATIONS@@"; perlcode 0 my $fr='@@ADMINEMAIL@@'; perlcode 0 my $pwc='@@PHCEMAIL@@'; perlcode 0 my $hostname="@@HOSTNAME@@"; perlcode 0 my $traphost="@@TRAPHOST@@"; perlcode 0 my $snmpargs="-v 2c -c zimbra $traphost ''"; perlcode 0 my $snmptrap="/opt/zimbra/common/bin/snmptrap $snmpargs"; perlcode 0 my $snmpsvctrap="ZIMBRA-TRAP-MIB::zmServiceStatusTrap"; perlcode 0 my $snmpsvcname="ZIMBRA-MIB::zmServiceName"; perlcode 0 my $snmpsvcstatus="ZIMBRA-MIB::zmServiceStatus"; perlcode 0 use Zimbra::SMTP; perlcode 0 my %statuses=('started'=>1,'stopped'=>0); perlcode 0 sub donotify { my %args = (@_); if ($args{HOST} eq "localhost") {$args{HOST}=$hostname;}; if ($notifications{smtp}) { dosmtp(%args) if $args{SERVICE}; dodisksmtp(%args) if $args{DISK};}; if ($notifications{snmp}) {dosnmp(%args);}; } perlcode 0 sub dosmtp { my %args = @_; if (my $smtp=Zimbra::SMTP->new) {unless($smtp->send(from=>$fr,to=>$pwc,subject=>"Service $args{SERVICE} $args{STATUS} on $args{HOST}",message=>$args{MESSAGE})){warn "message send failed: ",$smtp->error}} else {warn "failed new Zimbra::SMTP: ",Zimbra::SMTP->error} } perlcode 0 sub dodisksmtp { my %args = (@_); print "SMTP notification: $args{MESSAGE}\n"; if (my $smtp=Zimbra::SMTP->new) {unless($smtp->send(from=>$fr,to=>$pwc,subject=>"Disk $args{DISK} at $args{UTIL}\% on $args{HOST}",message=>$args{MESSAGE})){warn "message send failed: ",$smtp->error}}else{warn "failed new Zimbra::SMTP: ",Zimbra::SMTP->error}} perlcode 0 sub dosnmp { my %args = (@_); print "SNMP notification: $args{MESSAGE}\n"; `$snmptrap $snmpsvctrap $snmpsvcname s $args{SERVICE} $snmpsvcstatus i $statuses{$args{STATUS}}`; } ignore /DEBUG/ watchfor /: Service status change: (\S+) (.*) changed from stopped to running/ donotify SERVICE=$2,STATUS=started,HOST=$1 watchfor /: Service status change: (\S+) (.*) changed from running to stopped/ donotify SERVICE=$2,STATUS=stopped,HOST=$1 watchfor /err: Disk warning: (\S+) (\S+) on device (\S+) at (\d+)/ donotify DISK=$2,UTIL=$4,HOST=$1 watchfor /crit: Disk warning: (\S+) (\S+) on device (\S+) at (\d+)/ donotify DISK=$2,UTIL=$4,HOST=$1 ================================================ FILE: rpmconf/Conf/zmssl.cnf.in ================================================ # # OpenSSL example configuration file. # This is mostly being used for generation of certificate requests. # # This definition stops the following lines choking if HOME isn't # defined. HOME = /opt/zimbra/ssl RANDFILE = /opt/zimbra/ssl/.rnd # Extra OBJECT IDENTIFIER info: #oid_file = $ENV::HOME/.oid oid_section = new_oids # To use this configuration file with the "-extfile" option of the # "openssl x509" utility, name here the section containing the # X.509v3 extensions to use: # extensions = # (Alternatively, use a configuration file that has only # X.509v3 extensions in its main [= default] section.) [ new_oids ] # We can add new OIDs in here for use by 'ca' and 'req'. # Add a simple OID like this: # testoid1=1.2.3.4 # Or use config file substitution like this: # testoid2=${testoid1}.5.6 #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] dir = /opt/zimbra/ssl/zimbra/ca # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. #unique_subject = no # Set to 'no' to allow creation of # several ctificates with same subject. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = /opt/zimbra/ssl/zimbra/ca/ca.srl # The current serial number crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key RANDFILE = $dir/private/.rand # private random number file x509_extensions = usr_cert # The extentions to add to the cert # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options # Extension copying option: use with caution. copy_extensions = copy # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs # so this is commented out by default to leave a V1 CRL. # crl_extensions = crl_ext default_days = 1825 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = @@ssl_default_digest@@ # which md to use. preserve = no # keep passed DN ordering # A few difference way of specifying how similar the request should look # For type CA, the listed attributes must be the same, and the optional # and supplied fields are just that :-) policy = policy_match # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional # For the 'anything' policy # At this point in time, you must list all acceptable 'object' # types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ req ] default_bits = 1024 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca # The extentions to add to the self signed cert # Passwords for private keys if not present they will be prompted for # input_password = secret # output_password = secret # This sets a mask for permitted string types. There are several options. # default: PrintableString, T61String, BMPString. # pkix : PrintableString, BMPString (PKIX recommendation before 2004) # utf8only: only UTF8Strings (PKIX recommendation after 2004). # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). # MASK:XXXX a literal mask value. # WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. string_mask = utf8only req_extensions = v3_req # The extensions to add to a certificate request [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = US countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = N/A localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) 0.organizationName_default = N/A # we can do this but it is not needed normally :-) #1.organizationName = Second Organization Name (eg, company) #1.organizationName_default = World Wide Web Pty Ltd organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = Zimbra Collaboration Suite commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 commonName_default = @@HOSTNAME@@ emailAddress = Email Address emailAddress_max = 64 # SET-ex3 = SET extension number 3 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ usr_cert ] # These extensions are added when 'ca' signs a request. # This goes against PKIX guidelines but some CAs do it and some software # requires this to avoid interpreting an end user certificate as a CA. basicConstraints=CA:FALSE # Here are some examples of the usage of nsCertType. If it is omitted # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. # nsCertType = server # For an object signing certificate this would be used. # nsCertType = objsign # For normal client use this is typical # nsCertType = client, email # and for everything including object signing: # nsCertType = client, email, objsign # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment # This will be displayed in Netscape's comment listbox. nsComment = "OpenSSL Generated Certificate" # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer:always # This stuff is for subjectAltName and issuerAltname. # Import the email address. # subjectAltName=email:copy # An alternative to produce certificates that aren't # deprecated according to PKIX. # subjectAltName=email:move # Copy subject details # issuerAltName=issuer:copy #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem #nsBaseUrl #nsRevocationUrl #nsRenewalUrl #nsCaPolicyUrl #nsSslServerName @@SUBJECT_ALT_NAMES@@ [ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment @@SUBJECT_ALT_NAMES@@ [ v3_ca ] # Extensions for a typical CA # PKIX recommendation. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer:always # This is what PKIX recommends but some broken software chokes on critical # extensions. #basicConstraints = critical,CA:true # So we do this instead. basicConstraints = CA:true # Key usage: this is typical for a CA certificate. However since it will # prevent it being used as an test self-signed certificate it is best # left out by default. # keyUsage = cRLSign, keyCertSign # Some might want this also # nsCertType = sslCA, emailCA # Include email address in subject alt name: another PKIX recommendation # subjectAltName=email:copy # Copy issuer details # issuerAltName=issuer:copy @@SUBJECT_ALT_NAMES@@ # DER hex encoding of an extension: beware experts only! # obj=DER:02:03 # Where 'obj' is a standard or added object # You can even override a supported extension: # basicConstraints= critical, DER:30:03:01:01:FF [ crl_ext ] # CRL extensions. # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. # issuerAltName=issuer:copy authorityKeyIdentifier=keyid:always,issuer:always ================================================ FILE: rpmconf/Ctl/zimbra.cf.in ================================================ # Order is important. # # APPLICATION name executable "args" mode "label" # # mode = "normal" # # SERVICE name "label" appname monitor_port control_syntax # # CONTROL_SYNTAX name cmd "syntax" # CONTROL_SYNTAX proto "protocol-type" (text, http, soap) # # commands: start, restart, stop, exit, drain, status # plus app specific stuff # # $nm, $ex, $args, $md, $label # exit_status_error_mappings # log_message_alerts # PORT 7777 CONTROL_SYNTAX zimbrasyntax proto "text" CONTROL_SYNTAX zimbrasyntax start "START" CONTROL_SYNTAX zimbrasyntax restart "RESTART" CONTROL_SYNTAX zimbrasyntax stop "STOP" CONTROL_SYNTAX zimbrasyntax exit "EXIT" CONTROL_SYNTAX zimbrasyntax drain "DRAIN" CONTROL_SYNTAX zimbrasyntax status "STATUS" CONTROL_SYNTAX zimbrasyntax statuschange "STATUSCHANGE" CONTROL_SYNTAX zimbrasyntax events "EVENTS" CONTROL_SYNTAX zimbrasyntax addhost "ADDHOST" CONTROL_SYNTAX zimbrasyntax removehost "REMOVEHOST" CONTROL_SYNTAX zimbrasyntax shutdown "SHUTDOWN" CONTROL_SYNTAX zimbrasyntax reload "RELOAD" CONTROL_SYNTAX zimbrasyntax newfetchref "NEWFETCHREF" CONTROL_SYNTAX zimbrasyntax getfetchref "GETFETCHREF" ================================================ FILE: rpmconf/Ctl/zimbracore.cf ================================================ APPLICATION mysql test_server "9999" normal "mysql server" CONTROL_SYNTAX zimbrasyntax mysql_start "/opt/zimbra/bin/mysql.server start" CONTROL_SYNTAX zimbrasyntax mysql_stop "/opt/zimbra/bin/mysql.server stop" CONTROL_SYNTAX zimbrasyntax mysql_status "/opt/zimbra/bin/mysqladmin status" ================================================ FILE: rpmconf/Ctl/zimbraldap.cf ================================================ APPLICATION ldap test_server "9999" normal "ldap server" SERVICE ldap "Zimbra Directory" ldap CONTROL_SYNTAX zimbrasyntax ldap_start "/opt/zimbra/bin/ldap start" CONTROL_SYNTAX zimbrasyntax ldap_stop "/opt/zimbra/bin/ldap stop" CONTROL_SYNTAX zimbrasyntax ldap_status "/opt/zimbra/bin/ldap status" ================================================ FILE: rpmconf/Ctl/zimbralogger.cf ================================================ SERVICE logger "Zimbra Mail Console" logmysql,logswatch APPLICATION logmysql test_server "9999" normal "mysql server" CONTROL_SYNTAX zimbrasyntax logmysql_start "/opt/zimbra/bin/logmysql.server start" CONTROL_SYNTAX zimbrasyntax logmysql_stop "/opt/zimbra/bin/logmysql.server stop" CONTROL_SYNTAX zimbrasyntax logmysql_status "/opt/zimbra/bin/logmysqladmin status" APPLICATION logswatch test_server "9999" normal "logger swatch daemon" CONTROL_SYNTAX zimbrasyntax logswatch_start "/opt/zimbra/bin/zmlogswatchctl start" CONTROL_SYNTAX zimbrasyntax logswatch_stop "/opt/zimbra/bin/zmlogswatchctl stop" CONTROL_SYNTAX zimbrasyntax logswatch_status "/opt/zimbra/bin/zmlogswatchctl status" ================================================ FILE: rpmconf/Ctl/zimbramail.cf ================================================ SERVICE mailbox "Zimbra Mail Console" tomcat,mysql APPLICATION tomcat test_server "9999" normal "tomcat server" CONTROL_SYNTAX zimbrasyntax tomcat_start "/opt/zimbra/bin/tomcat start" CONTROL_SYNTAX zimbrasyntax tomcat_stop "/opt/zimbra/bin/tomcat stop" CONTROL_SYNTAX zimbrasyntax tomcat_kill "/opt/zimbra/bin/tomcat kill" CONTROL_SYNTAX zimbrasyntax tomcat_status "/opt/zimbra/bin/tomcat status" APPLICATION mysql test_server "9999" normal "mysql server" CONTROL_SYNTAX zimbrasyntax mysql_start "/opt/zimbra/bin/mysql.server start" CONTROL_SYNTAX zimbrasyntax mysql_stop "/opt/zimbra/bin/mysql.server stop" CONTROL_SYNTAX zimbrasyntax mysql_status "/opt/zimbra/bin/mysqladmin status" ================================================ FILE: rpmconf/Ctl/zimbramta.cf ================================================ SERVICE mta "Zimbra MTA" postfix,saslauthd,mtaconfig APPLICATION postfix test_server "9999" normal "Postfix mta" CONTROL_SYNTAX zimbrasyntax postfix_start "/opt/zimbra/bin/postfix start" CONTROL_SYNTAX zimbrasyntax postfix_stop "/opt/zimbra/bin/postfix stop" CONTROL_SYNTAX zimbrasyntax postfix_status "SMTP" SERVICE antispam "Zimbra MTA" amavisd,mtaconfig SERVICE antivirus "Zimbra MTA" amavisd,clamd,mtaconfig APPLICATION amavisd test_server "9999" normal "Postfix mta" CONTROL_SYNTAX zimbrasyntax amavisd_start "/opt/zimbra/bin/zmamavisdctl start" CONTROL_SYNTAX zimbrasyntax amavisd_stop "/opt/zimbra/bin/zmamavisdctl stop" CONTROL_SYNTAX zimbrasyntax amavisd_status "/opt/zimbra/bin/zmamavisdctl status" APPLICATION clamd test_server "9999" normal "Postfix mta" CONTROL_SYNTAX zimbrasyntax clamd_start "/opt/zimbra/bin/zmclamdctl start" CONTROL_SYNTAX zimbrasyntax clamd_stop "/opt/zimbra/bin/zmclamdctl stop" CONTROL_SYNTAX zimbrasyntax clamd_status "/opt/zimbra/bin/zmclamdctl status" APPLICATION mtaconfig test_server "9999" normal "MTA Configuration Daemon" CONTROL_SYNTAX zimbrasyntax mtaconfig_start "/opt/zimbra/bin/zmmtaconfigctl start" CONTROL_SYNTAX zimbrasyntax mtaconfig_stop "/opt/zimbra/bin/zmmtaconfigctl stop" CONTROL_SYNTAX zimbrasyntax mtaconfig_status "/opt/zimbra/bin/zmmtaconfigctl status" APPLICATION saslauthd test_server "9999" normal "SASL Auth Daemon" CONTROL_SYNTAX zimbrasyntax saslauthd_start "/opt/zimbra/bin/zmsaslauthdctl start" CONTROL_SYNTAX zimbrasyntax saslauthd_stop "/opt/zimbra/bin/zmsaslauthdctl stop" CONTROL_SYNTAX zimbrasyntax saslauthd_status "/opt/zimbra/bin/zmsaslauthdctl status" ================================================ FILE: rpmconf/Ctl/zimbrasnmp.cf ================================================ # SNMP COMMANDS HERE APPLICATION swatch test_server "9999" normal "SNMP monitor" SERVICE snmp "Zimbra MTA" swatch CONTROL_SYNTAX zimbrasyntax swatch_start "/opt/zimbra/bin/zmswatchctl start" CONTROL_SYNTAX zimbrasyntax swatch_stop "/opt/zimbra/bin/zmswatchctl stop" CONTROL_SYNTAX zimbrasyntax swatch_status "/opt/zimbra/bin/zmswatchctl status" ================================================ FILE: rpmconf/Env/crontabs/crontab ================================================ # ZIMBRASTART -- DO NOT EDIT ANYTHING BETWEEN THIS LINE AND ZIMBRAEND SHELL=/bin/bash # # Log pruning # 30 2 * * * find /opt/zimbra/log/ ! -name 'zmsetup*.log' -type f -name '*.log?*' -mtime +8 -exec rm {} \; > /dev/null 2>&1 35 2 * * * find /opt/zimbra/log/ -type f -name '*.out.????????????' -mtime +8 -exec rm {} \; > /dev/null 2>&1 # # compress logs manually to avoid application pauses when # handled through the log4j thread # 50 2 * * * /opt/zimbra/libexec/zmcompresslogs > /dev/null 2>&1 # # tmp dir cleaning # 40 2 * * * /opt/zimbra/libexec/zmcleantmp # # Status logging # */2 * * * * /opt/zimbra/libexec/zmstatuslog > /dev/null 2>&1 #*/10 * * * * /opt/zimbra/libexec/zmdisklog > /dev/null 2>&1 # # SSL Certificate Expiration Checks # 0 0 1 * * /opt/zimbra/libexec/zmcheckexpiredcerts -days 30 -email # # Backups # # BACKUP BEGIN # BACKUP END # # Storage Management # # STORAGE MANAGEMENT BEGIN # STORAGE MANAGEMENT END ================================================ FILE: rpmconf/Env/crontabs/crontab.ldap ================================================ # # crontab.ldap # # Monitor MDB database size */30 * * * * /opt/zimbra/libexec/zmldapmonitordb > /dev/null 2>&1 # ================================================ FILE: rpmconf/Env/crontabs/crontab.logger ================================================ # # crontab.logger # # process logs # 00,10,20,30,40,50 * * * * /opt/zimbra/libexec/zmlogprocess > /tmp/logprocess.out 2>&1 # # Graph generation # #10 * * * * /opt/zimbra/libexec/zmgengraphs >> /tmp/gengraphs.out 2>&1 # # Daily reports # 30 23 * * * /opt/zimbra/libexec/zmdailyreport -m ================================================ FILE: rpmconf/Env/crontabs/crontab.mta ================================================ # # crontab.mta # # # Queue logging # 0,10,20,30,40,50 * * * * /opt/zimbra/libexec/zmqueuelog # # Spam training # 0 22 * * * /opt/zimbra/bin/zmtrainsa >> /opt/zimbra/log/spamtrain.log 2>&1 # # Spam training cleanup # 45 23 * * * /opt/zimbra/bin/zmtrainsa --cleanup >> /opt/zimbra/log/spamtrain.log 2>&1 # # Spam rule updates # 45 0 * * * . /opt/zimbra/.bashrc; /opt/zimbra/libexec/zmsaupdate # # Spam Bayes auto-expiry # 20 23 * * * /opt/zimbra/common/bin/sa-learn --dbpath /opt/zimbra/data/amavisd/.spamassassin --force-expire --sync > /dev/null 2>&1 # # Clean up amavisd/tmp # 15 5,20 * * * find /opt/zimbra/data/amavisd/tmp -maxdepth 1 -type d -name 'amavis-*' -mtime +1 -exec rm -rf {} \; > /dev/null 2>&1 # # Clean up the quarantine dir # 0 1 * * * find /opt/zimbra/data/amavisd/quarantine -type f -mtime +7 -exec rm -f {} \; > /dev/null 2>&1 # # # 35 3 * * * /opt/zimbra/bin/zmcbpadmin --cleanup >/dev/null 2>&1 ================================================ FILE: rpmconf/Env/crontabs/crontab.store ================================================ # # crontab.store # # Log pruning # 30 2 * * * find /opt/zimbra/mailboxd/logs/ -type f -name \*log\* -mtime +8 -exec rm {} \; > /dev/null 2>&1 30 2 * * * find /opt/zimbra/log/ -type f -name stacktrace.\* -mtime +8 -exec rm {} \; > /dev/null 2>&1 # # Report on any database inconsistencies # 0 23 * * 7 /opt/zimbra/libexec/zmdbintegrityreport -m # # Monitor for multiple mysqld to prevent corruption # #*/5 * * * * /opt/zimbra/libexec/zmcheckduplicatemysqld -e > /dev/null 2>&1 # # Check zimbraVersionCheckURL for new update. # Only runs if this server matches zimbraVersionCheckServer # Only executes on zimbraVersionCheckInterval. min 2h interval # 18 */2 * * * /opt/zimbra/libexec/zmcheckversion -c >> /dev/null 2>&1 # # Invoke "ComputeAggregateQuotaUsageRequest" periodically # 15 2 * * * /opt/zimbra/libexec/zmcomputequotausage > /dev/null 2>&1 # # Invoke "client_usage_report.py" periodically to process /opt/zimbra/log/access_log* files # 55 1 * * * /opt/zimbra/libexec/client_usage_report.py > /dev/null 2>&1 # # Run zmgsaupdate util to trickeSync galsync accounts # 49 0 * * 7 /opt/zimbra/libexec/zmgsaupdate > /dev/null 2>&1 # # Password expiry reminders # 0 0 * * * /opt/zimbra/bin/zmpasswordexpiryreminder ================================================ FILE: rpmconf/Env/sudoers.d/01_zimbra ================================================ Defaults:zimbra !requiretty ================================================ FILE: rpmconf/Env/sudoers.d/02_zimbra-core ================================================ %zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmstat-fd * ================================================ FILE: rpmconf/Env/sudoers.d/02_zimbra-dnscache.deb ================================================ %zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmunbound %zimbra ALL=NOPASSWD:/sbin/resolvconf * ================================================ FILE: rpmconf/Env/sudoers.d/02_zimbra-dnscache.rpm ================================================ %zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmunbound %zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmdnscachealign * %zimbra ALL=NOPASSWD:/sbin/resolvconf * ================================================ FILE: rpmconf/Env/sudoers.d/02_zimbra-mta ================================================ %zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postfix %zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postalias %zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/qshape.pl %zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postconf %zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postsuper %zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/postcat %zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmqstat %zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmmtastatus %zimbra ALL=NOPASSWD:/opt/zimbra/common/sbin/amavis-mc ================================================ FILE: rpmconf/Env/sudoers.d/02_zimbra-store ================================================ %zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmmailboxdmgr ================================================ FILE: rpmconf/Env/zimbra.bash_profile ================================================ # .bash_profile umask 0027 # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs # this breaks unicode_start on vt consoles #BASH_ENV=$HOME/.bashrc #export BASH_ENV USERNAME="zimbra" export USERNAME export LANG=C export LC_ALL=C unset CLASSPATH unset DYLD_LIBRARY_PATH ================================================ FILE: rpmconf/Env/zimbra.bashrc ================================================ # .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' alias h='history 40' alias j='jobs' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi JAVA_HOME=/opt/zimbra/common/lib/jvm/java export JAVA_HOME PATH=/opt/zimbra/bin:${JAVA_HOME}/bin:/opt/zimbra/common/bin:/opt/zimbra/common/sbin:/usr/sbin:${PATH} export PATH unset LD_LIBRARY_PATH SNMPCONFPATH=/opt/zimbra/conf export SNMPCONFPATH eval `/usr/bin/perl -V:archname` PERLLIB=/opt/zimbra/common/lib/perl5/$archname:/opt/zimbra/common/lib/perl5 export PERLLIB PERL5LIB=$PERLLIB export PERL5LIB JYTHONPATH=/opt/zimbra/common/lib/jylibs export JYTHONPATH ulimit -n 524288 > /dev/null 2>&1 umask 0027 unset DISPLAY export MANPATH=/opt/zimbra/common/share/man:${MANPATH} export HISTTIMEFORMAT="%y%m%d %T " check_license_expiry() { local output json timestamp timestamp_no_z formatted_timestamp timestamp_epoch current_epoch remaining_days local zm_license_cache="/opt/zimbra/log/.zm_license_cache" local cache_dir cache_dir="$(dirname "$zm_license_cache")" if [ -f "$zm_license_cache" ] && [ "$(date +%Y-%m-%d -r "$zm_license_cache")" == "$(date +%Y-%m-%d)" ]; then output=$(cat "$zm_license_cache") else output=$(zmprov gcf zimbraNetworkRealtimeActivation 2>/dev/null) || return 0 if [ -d "$cache_dir" ]; then tmp_cache="$zm_license_cache.$$" echo "$output" > "$tmp_cache" && mv -f "$tmp_cache" "$zm_license_cache" fi fi [ -z "$output" ] && return 0 json=${output#zimbraNetworkRealtimeActivation: } [ -z "$json" ] && return 0 install_type=$(echo "$json" | grep -oP '"InstallType":"\K[^"]+' 2>/dev/null) [ -z "$install_type" ] && return 0 if [[ "$install_type" == "trial" || "$install_type" == "perpetual" || "$install_type" == "perpetualOfflineLicense" ]]; then return 0 fi timestamp=$(echo "$json" | grep -oP '"ValidUntilTimestamp":"\K[^"]+' 2>/dev/null) [ -z "$timestamp" ] && return 0 timestamp_no_z="${timestamp%Z}" formatted_timestamp=$(echo "$timestamp_no_z" | sed -E 's/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/\1-\2-\3 \4:\5:\6/') timestamp_epoch=$(date -d "$formatted_timestamp" +%s 2>/dev/null) [ -z "$timestamp_epoch" ] && return 0 current_epoch=$(date +%s 2>/dev/null) if [ "$timestamp_epoch" -lt "$current_epoch" ]; then remaining_days=-1 else remaining_days=$(( ((timestamp_epoch - current_epoch) / 86400) + 1 )) fi if [ "$remaining_days" -eq -1 ]; then echo -e "\e[31mLicense expiration alert: Your license is expired.\e[0m" elif [ "$remaining_days" -le 60 ]; then echo -e "\e[31mLicense expiration alert: Your license will expire in $remaining_days days.\e[0m" fi } # Only run this in interactive shells and if the zmlicense exists if [[ $- == *i* && -f /opt/zimbra/bin/zmlicense ]]; then check_license_expiry fi ================================================ FILE: rpmconf/Env/zimbra.exrc ================================================ set tabstop=4 set shiftwidth=4 set ai set nohlsearch set exrc ================================================ FILE: rpmconf/Env/zimbra.ldaprc ================================================ TLS_CACERTDIR /opt/zimbra/conf/ca TLS_REQCERT never ================================================ FILE: rpmconf/Env/zimbra.platform ================================================ @@BUILD_PLATFORM@@ ================================================ FILE: rpmconf/Env/zimbra.viminfo ================================================ ================================================ FILE: rpmconf/Install/Util/addUser.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # verifyExists() { EXISTS=0 NM=`/usr/bin/nifind /$1/$2` if [ "x$NM" != "x" ]; then EXISTS=1 fi } verifyAvailable() { verifyExists $1 $2 if [ $EXISTS = 1 ]; then echo "$1 $2 already exists!" exit 1 fi } getNextGID() { GID=`/usr/bin/nireport / /groups gid | sort -n | tail -1` GID=`expr $GID + 1` } getGIDByName() { IDS=`/usr/bin/niutil -read / /groups/$1 | egrep '^gid:' | sed -e 's/gid: //'` if [ "x$IDS" != "x" ]; then GID=$IDS fi } getNextUID() { NUID=`/usr/bin/nireport / /users uid | sort -n | tail -1` NUID=`expr $NUID + 1` } while [ $# != 0 ]; do case "$1" in -d) shift homedir=$1 ;; -g) shift maingroup=$1 ;; -G) shift auxgroups=$1 ;; *) name=$1 ;; esac shift done if [ "x$name" = "x" ]; then echo "You must specify a user name!" exit 1 fi if [ "x$maingroup" = "x" ]; then maingroup=$name fi auxgroups=`echo $auxgroups | sed -e 's/,/ /g'` verifyAvailable "users" $name for g in $auxgroups; do verifyExists groups $g if [ $EXISTS = 0 ]; then echo "Auxiliary group $g not found!" exit 1 else /usr/bin/niutil -mergeprop / /groups/$g users $name fi done verifyExists groups $maingroup if [ $EXISTS = 1 ]; then getGIDByName $maingroup creategroup=0 else getNextGID creategroup=1 fi maingid=$GID getNextUID mainuid=$NUID echo "Creating $name with UID $mainuid, GID $maingid" if [ $creategroup = 1 ]; then /usr/bin/niutil -create / /groups/$maingroup /usr/bin/niutil -createprop / /groups/$maingroup gid $maingid fi /usr/bin/niutil -mergeprop / /groups/$maingroup users $name niutil -create / /users/$name niutil -createprop / /users/$name realname $name niutil -createprop / /users/$name uid $mainuid niutil -createprop / /users/$name gid ${maingid} niutil -createprop / /users/$name shell /bin/bash if [ x$homedir != "x" ]; then niutil -createprop / /users/$name home $homedir fi exit 0 ================================================ FILE: rpmconf/Install/Util/globals.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # LOGFILE=`mktemp -t install.log.XXXXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } if [ -e "/tmp/install.log" ]; then rm "/tmp/install.log" fi ln -sf "$LOGFILE" "/tmp/install.log" PLATFORM=`bin/get_plat_tag.sh` CORE_PACKAGES="zimbra-core" PACKAGES="zimbra-ldap \ zimbra-logger \ zimbra-mta \ zimbra-dnscache \ zimbra-snmp \ zimbra-license-daemon \ zimbra-store \ zimbra-apache \ zimbra-spell \ zimbra-convertd \ zimbra-memcached \ zimbra-proxy \ zimbra-archiving \ zimbra-onlyoffice" SERVICES="" OPTIONAL_PACKAGES="zimbra-qatest \ zimbra-license-tools \ zimbra-license-extension \ zimbra-network-store" ZEXTRAS_PACKAGES="zimbra-connect \ zimbra-connect-modern \ zimbra-drive \ zimbra-drive-ng \ zimbra-drive-modern \ zimbra-docs \ zimbra-docs-modern \ zimbra-chat \ zimbra-talk \ zimbra-zimlet-auth \ zimbra-zimlet-briefcase-edit-lool \ zimbra-network-modules-ng" DEPRECATED_PACKAGES_IN_10="zimbra-zimlet-restore-contacts \ zimbra-zimlet-duplicate-contacts" MYDIR="$(CDPATH= cd "$(dirname "$0")" && pwd)" if [ "$(cat ${MYDIR}/.BUILD_TYPE)" == "NETWORK" ]; then OPTIONAL_PACKAGES="${OPTIONAL_PACKAGES} zimbra-modern-ui zimbra-modern-zimlets zimbra-zimlet-document-editor zimbra-zimlet-classic-document-editor zimbra-zimlet-classic-set-default-client zimbra-patch zimbra-mta-patch zimbra-proxy-patch zimbra-ldap-patch zimbra-onlyoffice-patch zimbra-lds-patch" fi PACKAGE_DIR="$(CDPATH= cd "$(dirname "$0")" && pwd)/packages" SAVEDIR="/opt/zimbra/.saveconfig" if [ x$RESTORECONFIG = "x" ]; then RESTORECONFIG=$SAVEDIR fi # # Initial values # AUTOINSTALL="no" INSTALLED="no" INSTALLED_PACKAGES="" REMOVE="no" UPGRADE="no" HOSTNAME=`hostname --fqdn` ZIMBRAINTERNAL=no echo $HOSTNAME | egrep -qe 'eng.synacor.com$|eng.zimbra.com$|lab.zimbra.com$|zimbradev.com$' > /dev/null 2>&1 if [ $? = 0 ]; then ZIMBRAINTERNAL=yes fi LDAPHOST="" LDAPPORT=389 fq=`isFQDN $HOSTNAME` if [ $fq = 0 ]; then HOSTNAME="" fi SERVICEIP=`hostname -i` SMTPHOST=$HOSTNAME SNMPTRAPHOST=$HOSTNAME SMTPSOURCE="none" SMTPDEST="none" SNMPNOTIFY="0" SMTPNOTIFY="0" INSTALL_PACKAGES="zimbra-core" STARTSERVERS="yes" LDAPROOTPW="" LDAPZIMBRAPW="" LDAPPOSTPW="" LDAPREPPW="" LDAPAMAVISPW="" LDAPNGINXPW="" if [ x"$ZIMBRAINTERNAL" = "xno" ]; then CREATEDOMAIN=$(hostname -d) # May be empty CREATEDOMAIN=${CREATEDOMAIN:-$HOSTNAME} # only go with fqdn if domain is empty else CREATEDOMAIN=$HOSTNAME fi CREATEADMIN="admin@${CREATEDOMAIN}" CREATEADMINPASS="" MODE="http" ALLOWSELFSIGNED="yes" RUNAV="" RUNSA="" AVUSER="" AVDOMAIN="" ================================================ FILE: rpmconf/Install/Util/modules/getconfig.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2007, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # getConfigOptions() { echo "" echo "Configuration section" if [ $STORE_HERE = "yes" -a $POSTFIX_HERE = "no" ]; then askNonBlank "Please enter the hostname for zimbraSmtpHostname" \ "$SMTPHOST" SMTPHOST=$response fi if [ $STORE_HERE = "yes" ]; then while :; do askNonBlank "Enter web server mode (http, https, mixed, redirect)" "$MODE" MODE=$response if [ $MODE = "http" -o $MODE = "https" -o $MODE = "mixed" -o $MODE = "redirect" ]; then break else echo "Please enter a valid mode" fi done if [ $ALLOWSELFSIGNED = "true" -o $ALLOWSELFSIGNED = "yes" ]; then ALLOWSELFSIGNED="yes" else ALLOWSELFSIGNED="no" fi # Hardcoding for bootstrap install. 20050725 MEM ALLOWSELFSIGNED="true" fi if [ $LDAP_HERE = "yes" ]; then LDAPHOST=$HOSTNAME LDAPPORT=389 if [ $UPGRADE = "no" ]; then su - zimbra -c "zmlocalconfig -e -r startup_ldap_password" LDAPROOTPW=`su - zimbra -c "zmlocalconfig -s -m nokey startup_ldap_password"` askNonBlank "Enter the root ldap password for $LDAPHOST:" \ "$LDAPROOTPW" LDAPROOTPW=$response su - zimbra -c "zmlocalconfig -e startup_ldap_password=''" fi else while :; do askNonBlank "Please enter the hostname for the ldap server" "$LDAPHOST" LDAPHOST=$response askInt "Please enter the port for the ldap server" "$LDAPPORT" LDAPPORT=$response if [ $LDAP_HERE = "no" -a $UPGRADE = "no" ]; then askNonBlank "Enter the root ldap password for $LDAPHOST:" \ "$LDAPROOTPW" LDAPROOTPW=$response askNonBlank "Enter the zimbra admin ldap password for $LDAPHOST:" \ LDAPZIMBRAPW=$response fi verifyLdapServer if [ $LDAPOK = "yes" ]; then break fi done fi if [ $UPGRADE = "no" ]; then if [ $POSTFIX_HERE = "yes" ]; then askYN "Enable Clam Anti-virus services?" "$RUNAV" RUNAV=$response if [ $RUNAV = "yes" ]; then if [ "x$AVUSER" = "x" ]; then AVUSER="notify@${HOSTNAME}" fi askNonBlank "Notification address for AV alerts?" "$AVUSER" AVUSER=$response AVDOMAIN=`echo $AVUSER | awk -F@ '{print $2}'` fi askYN "Enable SpamAssassin anti-spam services?" "$RUNSA" RUNSA=$response fi if [ $SNMP_HERE = "yes" ]; then askYN "Notify via SNMP?" "$SNMPNOTIFY" SNMPNOTIFY=$response if [ $SNMPNOTIFY = "yes" ]; then askNonBlank "SNMP Trap host?" "$SNMPTRAPHOST" SNMPTRAPHOST=$response SNMPNOTIFY=1 else SNMPNOTIFY=0 fi askYN "Notify via SMTP?" "$SMTPNOTIFY" SMTPNOTIFY=$response if [ $SMTPNOTIFY = "yes" ]; then askNonBlank "SMTP Source email address?" "$SMTPSOURCE" SMTPSOURCE=$response askNonBlank "SMTP Destination email address?" "$SMTPDEST" SMTPDEST=$response SMTPNOTIFY=1 else SMTPNOTIFY=0 fi fi askYN "Create a domain?" "Y" if [ $response = "yes" ]; then askNonBlank "Enter domain to create:" "$CREATEDOMAIN" CREATEDOMAIN=$response while :; do askYN "Create an admin account?" "Y" if [ $response = "yes" ]; then CREATEADMIN="admin@${CREATEDOMAIN}" askNonBlank "Enter admin account to create:" "$CREATEADMIN" CREATEADMIN=$response while :; do askNonBlankNoEcho "Enter admin password (min 6 chars):" "" len=`echo $response | wc -m` # Not sure why, but wc -m reports one too many if [ $len -gt 6 ]; then CREATEADMINPASS=$response askNonBlankNoEcho "Re-enter admin password (min 6 chars):" "" if [ $CREATEADMINPASS = $response ]; then break else echo "Passwords do not match!" fi else echo "Please enter a password 6 characters or longer" fi done admindomain=`echo $CREATEADMIN | awk -F@ '{print $2}'` if [ x$admindomain = x$CREATEDOMAIN ]; then break else echo "You must create an admin account under the domain $CREATEDOMAIN" fi else break fi done else CREATEDOMAIN="" CREATEADMIN="" CREATEADMINPASS="" fi fi } ================================================ FILE: rpmconf/Install/Util/modules/packages.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # installPackages() { echo echo "Beginning Installation - see $LOGFILE for details..." echo pretty_display() { local banner=$1; shift; local pk=("$@"); echo echo "$banner (${#pk[*]}):" | tee -a $LOGFILE local p; for p in "${pk[@]}" do echo " $(basename $p)" | tee -a $LOGFILE done echo -n " ..."; echo >> $LOGFILE } gather_package_info() { local pkg=$1; shift; if [ -z "${gather_visit_flag[$pkg]}" ] then echo "gathering packgage info for: $pkg" >> $LOGFILE locatePackage $pkg gather_visit_flag[$pkg]=1 if [ "${global_pkg_loc[$pkg]}" == "local" ] then local deps=( $(LocalPackageDepList "${global_pkg_file[$pkg]}") ) local dep for dep in "${deps[@]}" do echo "descending into dependency: $pkg (local) --deps-> $dep" >> $LOGFILE gather_package_info "$dep" done printf "%48s %s\n" "$pkg" "will be installed." local_pkg_names+=( "$pkg" ) local_pkg_files+=( "${global_pkg_file[$pkg]}" ) elif [ "${global_pkg_loc[$pkg]}" == "repo" ] then local delay=0 if ! [[ "$pkg" =~ ^zimbra-.*-components$ ]] then local dep for dep in $(RepoPackageDepList "$pkg") do echo "locating dependency: $pkg (remote) --deps-> $dep" >> $LOGFILE locatePackage "$dep" if [ "${global_pkg_loc[$dep]}" == "local" ] then delay=1 fi done fi if [ "$delay" == "1" ] then printf "%48s %s\n" "$pkg" "will be downloaded and installed (later)." repo_pkg_names_delayed+=( "$pkg" ) else printf "%48s %s\n" "$pkg" "will be downloaded and installed." repo_pkg_names+=( "$pkg" ) fi else printf "%48s %s\n" "$pkg" "is missing. ERROR"; (( ++gather_dep_errors )) fi gather_visit_flag[$pkg]=2 fi } local -A gather_visit_flag=() local gather_dep_errors=0 local repo_pkg_names_delayed=() local repo_pkg_names=() local local_pkg_names=() local local_pkg_files=() local PKG; for PKG in $INSTALL_PACKAGES do gather_package_info $PKG; done if [ "$gather_dep_errors" -gt 0 ] then echo echo "Unable to find missing packages in repository. System is not modified." exit 1 fi if [ "${#repo_pkg_names[@]}" -gt 0 ] then # Download packages. pretty_display "Downloading packages" "${repo_pkg_names[@]}"; $PACKAGEDOWNLOAD "${repo_pkg_names[@]}" >> $LOGFILE 2>&1 if [ $? -ne 0 ]; then echo "Unable to download packages from repository. System is not modified." exit 1 fi echo "done" fi if [ $UPGRADE = "yes" ]; then if [ "${ZM_CUR_MAJOR}" -lt 8 ] || [ "${ZM_CUR_MAJOR}" -eq 8 -a "${ZM_CUR_MINOR}" -lt 7 ]; then POST87UPGRADE="false" else POST87UPGRADE="true" fi if [ "$FORCE_UPGRADE" = "yes" -o "$POST87UPGRADE" = "false" ]; then findUbuntuExternalPackageDependencies fi saveExistingConfig fi removeExistingInstall installEPELRepo if [ "${#repo_pkg_names[@]}" -gt 0 ] then pretty_display "Installing repo packages" "${repo_pkg_names[@]}"; $REPOINST "${repo_pkg_names[@]}" >>$LOGFILE 2>&1 if [ $? != 0 ]; then pkgError fi echo "done" fi if [ "${#local_pkg_files[@]}" -gt 0 ] then pretty_display "Installing local packages" "${local_pkg_names[@]}"; $PACKAGEINST "${local_pkg_files[@]}" >> $LOGFILE 2>&1 if [ $? != 0 ]; then pkgError fi echo "done" fi if [ "${#repo_pkg_names_delayed[@]}" -gt 0 ] then pretty_display "Installing extra packages" "${repo_pkg_names_delayed[@]}"; $REPOINST "${repo_pkg_names_delayed[@]}" >>$LOGFILE 2>&1 if [ $? != 0 ]; then echo "Unable to download extra packages from repository. Proceeding without this..." # not exiting on error else echo "done" fi fi if [ $UPGRADE = "yes" ]; then ST="UPGRADED" else ST="INSTALLED" fi D=`date +%s` if [ "$ISUBUNTU" = "true" ] && [ ! -z "$EXTPACKAGES" ]; then echo -n "Re-installing $EXTPACKAGES ..." $REPOINST $EXTPACKAGES >> $LOGFILE 2>&1 if [ $? -ne 0 ]; then echo "Failed to install package[s] $EXTPACKAGES." # not exiting on error fi echo "done" fi local pkg_n for pkg_n in "${local_pkg_names[@]}" "${repo_pkg_names[@]}" "${repo_pkg_names_delayed[@]}" do echo "${D}: $ST $(DumpFileDetailsFromPackage "$pkg_n")" >> /opt/zimbra/.install_history done echo echo "Running Post Installation Configuration:" } pkgError() { echo "" echo "ERROR: Unable to install required packages" if [ $UPGRADE = "yes" ]; then echo "WARNING: REMOTE PACKAGE INSTALLATION FAILED." echo "To proceed, review the instructions at:" echo "https://wiki.zimbra.com/wiki/Recovering_from_upgrade_failure" echo "Failure to follow the instructions on the wiki will result in complete data loss." else echo "Fix the issues with remote package installation and rerun the installer" fi exit 1 } declare -A global_pkg_loc declare -A global_pkg_file locatePackage() { local package="$1"; shift; if [ -z "${global_pkg_loc[$package]}" ] then local check_file="$(echo "$PACKAGE_DIR/$package"[-_][0-9]*."$PACKAGEEXT")" if [ -f "$check_file" ] then global_pkg_loc[$package]="local" global_pkg_file[$package]=$check_file else if grep -q -w -e "^$package" <(LocatePackageInRepo "$package") then global_pkg_loc[$package]="repo" global_pkg_file[$package]="" else global_pkg_loc[$package]="unknown" global_pkg_file[$package]="" fi fi fi } checkPackages() { echo "" echo "Checking for installable packages" echo "" AVAILABLE_PACKAGES="" local package for package in $CORE_PACKAGES $PACKAGES $OPTIONAL_PACKAGES; do locatePackage $package if [ "${global_pkg_loc[$package]}" == "local" ] then local file=${global_pkg_file[$package]} if grep -q i386 <(echo $file) then PROC="i386" else PROC="x86_64" fi if [[ $PLATFORM == "DEBIAN"* || $PLATFORM == "UBUNTU"* ]]; then LOCALPROC=`dpkg --print-architecture` if [ x"$LOCALPROC" == "xamd64" ]; then LOCALPROC="x86_64" fi else LOCALPROC=`uname -i` fi if [ x$LOCALPROC != x$PROC ]; then echo "Error: attempting to install $PROC packages on a $LOCALPROC OS." echo "Exiting..." echo "" exit 1 fi file_check="unverified" if [ x"$PACKAGEVERIFY" != "x" ]; then if $PACKAGEVERIFY $file > /dev/null 2>&1 then file_check="verified"; else echo "Found $package locally, but package is not installable. (possibly corrupt)" echo "Unable to continue. Please correct package corruption and rerun the installation." exit 1 fi fi if ! grep -q -w -e "$package" <(echo "$CORE_PACKAGES") then AVAILABLE_PACKAGES="$AVAILABLE_PACKAGES $package" fi printf "%s\n" "Found $package (local)" elif [ "${global_pkg_loc[$package]}" == "repo" ] then if ! grep -q -w -e "$package" <(echo "$CORE_PACKAGES") then AVAILABLE_PACKAGES="$AVAILABLE_PACKAGES $package" fi printf "%s\n" "Found $package (repo)" else if grep -q -w -e "$package" <(echo "$CORE_PACKAGES") then echo "ERROR: Required Core package $package not found in $PACKAGE_DIR" echo "Exiting" exit 1 fi fi done echo "" } ================================================ FILE: rpmconf/Install/Util/modules/postinstall.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # postInstallConfig() { echo "" echo "Post installation configuration" echo "" chmod 755 /opt/zimbra if [ $UPGRADE = "yes" ]; then #restore old config, then overwrite... restoreExistingConfig fi if [ $UPGRADE = "no" -a $STORE_HERE = "yes" ]; then echo -n "Creating db..." runAsZimbra "/opt/zimbra/libexec/zmmyinit" echo "done" fi if [ $LOGGER_HERE = "yes" ]; then if [ ! -d "/opt/zimbra/logger/db/data" ]; then echo -n "Creating logger db..." runAsZimbra "/opt/zimbra/libexec/zmloggerinit" echo "done" fi fi echo -n "Setting the hostname to $HOSTNAME..." runAsZimbra "zmlocalconfig -e zimbra_server_hostname=${HOSTNAME}" echo "done" echo -n "Setting the LDAP host to $LDAPHOST..." runAsZimbra "zmlocalconfig -e ldap_host=$LDAPHOST" runAsZimbra "zmlocalconfig -e ldap_port=$LDAPPORT" echo "done" SERVERCREATED="no" if [ $UPGRADE = "no" ]; then if [ $LDAP_HERE = "yes" ]; then echo -n "Initializing ldap..." runAsZimbra "/opt/zimbra/libexec/zmldapinit $LDAPROOTPW $LDAPZIMBRAPW" echo "done" else # set the ldap password in localconfig only echo -n "Setting the ldap passwords..." runAsZimbra "zmlocalconfig -f -e ldap_root_password=$LDAPROOTPW" runAsZimbra "zmlocalconfig -f -e zimbra_ldap_password=$LDAPZIMBRAPW" runAsZimbra "zmlocalconfig -f -e ldap_postfix_password=$LDAPPOSTPW" runAsZimbra "zmlocalconfig -f -e ldap_replication_password=$LDAPREPPW" runAsZimbra "zmlocalconfig -f -e ldap_amavis_password=$LDAPAMAVISPW" runAsZimbra "zmlocalconfig -f -e ldap_nginx_password=$LDAPNGINXPW" echo "done" fi echo -n "Creating server $HOSTNAME..." runAsZimbra "zmprov cs $HOSTNAME" if [ $? = 0 ]; then SERVERCREATED="yes" fi echo "done" if [ x$CREATEDOMAIN != "x" ]; then echo -n "Creating domain $CREATEDOMAIN..." runAsZimbra "zmprov cd $CREATEDOMAIN" runAsZimbra "zmprov mcf zimbraDefaultDomainName $CREATEDOMAIN" echo "done" if [ x$CREATEADMIN != "x" ]; then echo -n "Creating admin account $CREATEADMIN..." runAsZimbra "zmprov ca $CREATEADMIN $CREATEADMINPASS zimbraIsAdminAccount TRUE" LOCALHOSTNAME=`hostname --fqdn` if [ $LOCALHOSTNAME = $CREATEDOMAIN ]; then runAsZimbra "zmprov aaa $CREATEADMIN postmaster@$HOSTNAME" fi echo "done" fi fi else if [ $LDAP_HERE = "yes" ]; then echo -n "Starting ldap..." runAsZimbra "ldap start" runAsZimbra "zmldapapplyldif" echo "done" fi fi if [ $LDAP_HERE = "yes" ]; then SERVICES="zimbraServiceInstalled ldap" fi if [ $LOGGER_HERE = "yes" ]; then SERVICES="$SERVICES zimbraServiceInstalled logger" runAsZimbra "zmprov mcf zimbraLogHostname $HOSTNAME" fi if [ $STORE_HERE = "yes" ]; then if [ $SERVERCREATED = "yes" ]; then echo -n "Setting smtp host to $SMTPHOST..." runAsZimbra "zmprov ms $HOSTNAME zimbraSmtpHostname $SMTPHOST" echo "done" fi echo -n "Adding $HOSTNAME to zimbraMailHostPool in default COS..." runAsZimbra "id=\`zmprov gs $HOSTNAME | grep zimbraId | awk '{print \$2}'\`; for i in \`zmprov gc default | grep zimbraMailHostPool | sed 's/zimbraMailHostPool: //'\`; do host=\"\$host zimbraMailHostPool \$i\"; done; zmprov mc default \$host zimbraMailHostPool \$id" echo "done" SERVICES="$SERVICES zimbraServiceInstalled mailbox" fi if [ $POSTFIX_HERE = "yes" ]; then echo -n "Initializing mta config..." runAsZimbra "/opt/zimbra/libexec/zmmtainit $LDAPHOST" echo "done" # zmprov isn't very friendly SERVICES="$SERVICES zimbraServiceInstalled mta" if [ $RUNAV = "yes" ]; then SERVICES="$SERVICES zimbraServiceInstalled antivirus" runAsZimbra "zmlocalconfig -e av_notify_user=$AVUSER" runAsZimbra "zmlocalconfig -e av_notify_domain=$AVDOMAIN" fi if [ $RUNSA = "yes" ]; then SERVICES="$SERVICES zimbraServiceInstalled antispam" fi fi if [ $SNMP_HERE = "yes" ]; then echo -n "Configuring SNMP..." runAsZimbra "zmlocalconfig -e snmp_notify=$SNMPNOTIFY" runAsZimbra "zmlocalconfig -e smtp_notify=$SMTPNOTIFY" runAsZimbra \ "zmlocalconfig -e snmp_trap_host=$SNMPTRAPHOST" runAsZimbra "zmlocalconfig -e smtp_source=$SMTPSOURCE" runAsZimbra \ "zmlocalconfig -e smtp_destination=$SMTPDEST" runAsZimbra "zmsnmpinit" echo "done" SERVICES="$SERVICES zimbraServiceInstalled snmp" fi echo -n "Setting services on $HOSTNAME..." runAsZimbra "zmprov -r ms $HOSTNAME $SERVICES" ENABLEDSERVICES=`echo $SERVICES | sed -e 's/zimbraServiceInstalled/zimbraServiceEnabled/g'` runAsZimbra "zmprov -r ms $HOSTNAME $ENABLEDSERVICES" LOCALSERVICES=`echo $SERVICES | sed -e 's/zimbraServiceInstalled //g'` runAsZimbra "zmlocalconfig -e zimbra_services=\"$LOCALSERVICES\"" echo "done" if [ $STORE_HERE = "yes" -o $POSTFIX_HERE = "yes" ]; then echo -n "Setting up SSL..." runAsZimbra "zmcreatecert" if [ $STORE_HERE = "yes" ]; then runAsZimbra "zmcertinstall mailbox" runAsZimbra "zmtlsctl $MODE" fi if [ $POSTFIX_HERE = "yes" ]; then runAsZimbra "zmcertinstall mta /opt/zimbra/ssl/ssl/server/smtpd.crt /opt/zimbra/ssl/ssl/ca/ca.key" fi runAsZimbra "zmlocalconfig -e ssl_allow_untrusted_certs=$ALLOWSELFSIGNED" echo "done" if [ $UPGRADE = "yes" ]; then restoreCerts fi fi setupCrontab } ================================================ FILE: rpmconf/Install/Util/utilfunc.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # displayLicense() { echo "" echo "" if [ -f ${MYDIR}/docs/zcl.txt ]; then cat $MYDIR/docs/zcl.txt elif [ -f ${MYDIR}/docs/zimbra_network_eula.txt ]; then cat ${MYDIR}/docs/zimbra_network_eula.txt fi echo "" echo "" if [ x$DEFAULTFILE = "x" ]; then askYN "Do you agree with the terms of the software license agreement?" "N" if [ $response != "yes" ]; then exit fi fi echo "" } isFQDN() { #fqdn is > 2 dots. because I said so. if [ x"$1" = "x" ]; then echo 0 return fi NF=`echo $1 | awk -F. '{print NF}'` if [ $NF -ge 2 ]; then echo 1 else echo 0 fi } verifyIPv6() { IP=$1 BAD_IP=`echo $IP | awk -F: '{ RES=0; SHORT=0; LSHORT=0; if (NF > 8) { RES=1 } else { for (BLK = 1; BLK <= NF; BLK++) { if ($BLK !~ /^[0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$/) { if ($BLK == "") { if (SHORT > 0) { if ((BLK - LSHORT) != 1) { RES = 1 } } SHORT++; LSHORT = BLK } else { RES = 1 } } } } if ((NF == 3) && ($2 != "")) { RES = 1 } if (((SHORT > 2) && (NF != 3)) || ((SHORT == 2) && (!(($2 == "") || ($(NF-1) == ""))))) { RES = 1 } if ((NF - SHORT) > 6 ) { RES = 1 } if ((SHORT == 0) && (NF < 8)) { RES = 1 } print RES }'` return ${BAD_IP} } verifyMixedIPv6() { IP=$1 BAD_IP=`echo $IP | awk -F: '{ RES=0; SHORT=0; LSHORT=0; if (NF > 8) { RES=1 } else { for (BLK = 1; BLK <= NF; BLK++) { if ($BLK !~ /^[0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$|^[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$/) { if ($BLK == "") { if (SHORT > 0) { if ((BLK - LSHORT) != 1) { RES = 1 } } SHORT++; LSHORT = BLK } else { RES = 1 } } } } if ((NF == 3) && ($2 != "")) { RES = 1 } if (((SHORT > 2) && (NF != 3)) || ((SHORT == 2) && (!(($2 == "") || ($(NF-1) == ""))))) { RES = 1 } if ((NF - SHORT) > 6 ) { RES = 1 } if ((SHORT == 0) && (NF < 6)) { RES = 1 } print RES }'` return ${BAD_IP} } verifyIPv4() { IP=$1 BAD_IP=0; if [ "`echo $IP | sed -ne 's/[0-9]//gp'`" != "..." ] then BAD_IP=1 else BAD_IP=`echo $IP | awk -F. 'BEGIN {BAD_OCTET=0} { for (OCTET = 1; OCTET <= 4; OCTET++) { if (($OCTET !~ /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/) || ((OCTET == 1) && ($OCTET == "0"))) { BAD_OCTET=1 } } } END { print BAD_OCTET }'` fi return ${BAD_IP} } saveConfig() { FILE=$1 cat > $FILE < /dev/null 2>&1 if [ $? = 0 ]; then break fi fi echo "A numeric answer is required" done } askInstallPkgYN() { PROMPT="$1" REQUIRE_STORE="$2" YES_STORE_DEFAULT="$3" NO_STORE_DEFAULT="$4" if [ "$STORE_SELECTED" = "yes" ]; then askYN "$PROMPT" "$YES_STORE_DEFAULT" else if [ "$REQUIRE_STORE" = "yes" ]; then askYN "$PROMPT" "$NO_STORE_DEFAULT" fi fi } ifStoreSelectedY() { if [ "$STORE_SELECTED" = "yes" ]; then response="yes" fi } checkUser() { user=$1 if [ x`whoami` != x$user ]; then echo Error: must be run as $user user exit 1 fi } checkMySQLConfig() { isInstalled zimbra-store if [ x$PKGINSTALLED != "x" ]; then if [ -f "/opt/zimbra/conf/my.cnf" ]; then BIND_ADDR=`awk '{ if ( $1 ~ /^bind-address$/ ) { print $3 } }' /opt/zimbra/conf/my.cnf` while [ "${BIND_ADDR}x" != "127.0.0.1x" -a "${BIND_ADDR}x" != "localhostx" ]; do echo "The MySQL bind address is currently not set to \"localhost\" or \"127.0.0.1\". Due to a" echo "MySQL bug (#61713), the MySQL bind address must be set to \"127.0.0.1\". Please correct" echo "the bind-address entry in the \"/opt/zimbra/conf/my.cnf\" file to proceed with the upgrade." askYN "Retry validation? (Y/N)?" "Y" if [ $response = "no" ]; then break fi BIND_ADDR=`awk '{ if ( $1 ~ /^bind-address$/ ) { print $3 } }' /opt/zimbra/conf/my.cnf` done if [ "${BIND_ADDR}x" != "127.0.0.1x" -a "${BIND_ADDR}x" != "localhostx" ]; then echo "" echo "It is recommended that the bind-address setting in the /opt/zimbra/conf/my.cnf file be set" echo "to \"127.0.0.1\". The current setting of \"${BIND_ADDR}\" is not supported within" echo "ZCS and may cause the installation to fail." askYN "Proceed with installation? (Y/N)?" "N" if [ $response != "yes" ]; then echo "" echo "Aborting installation" echo "" exit 1 fi fi fi fi } checkDatabaseIntegrity() { isInstalled zimbra-store if [ x$PKGINSTALLED != "x" ]; then if [ -x "bin/zmdbintegrityreport" -a -x "/opt/zimbra/bin/mysqladmin" ]; then while :; do if [ x$DEFAULTFILE = "x" ]; then askYN "Do you want to verify message store database integrity?" "Y" if [ $response = "no" ]; then break fi elif [ x$VERIFYMSGDB != "xyes" ]; then break fi echo "Verifying integrity of message store databases. This may take a while." su - zimbra -c "/opt/zimbra/bin/mysqladmin -s ping" 2>/dev/null if [ $? != 0 ]; then su - zimbra -c "/opt/zimbra/bin/mysql.server start" 2> /dev/null for ((i = 0; i < 60; i++)) do su - zimbra -c "/opt/zimbra/bin/mysqladmin -s ping" 2>/dev/null if [ $? = 0 ]; then SQLSTARTED=1 break fi sleep 2 done fi MAILBOXDBINTEGRITYOUTPUT=$(perl bin/zmdbintegrityreport -v -r 2>&1) MAILBOXDBINTEGRITYSTATUS=$? echo "$MAILBOXDBINTEGRITYOUTPUT" if [ x"$SQLSTARTED" != "x" ]; then su - zimbra -c "/opt/zimbra/bin/mysqladmin -s ping" 2>/dev/null if [ $? = 0 ]; then su - zimbra -c "/opt/zimbra/bin/mysql.server stop" 2> /dev/null for ((i = 0; i < 60; i++)) do su - zimbra -c "/opt/zimbra/bin/mysqladmin -s ping" 2>/dev/null if [ $? != 0 ]; then break fi sleep 2 done fi fi if [ $MAILBOXDBINTEGRITYSTATUS != 0 ]; then if echo "$MAILBOXDBINTEGRITYOUTPUT" | grep -q "Database errors found" && echo "$MAILBOXDBINTEGRITYOUTPUT" | grep -q "Orphan accounts detected"; then exit $MAILBOXDBINTEGRITYSTATUS elif echo "$MAILBOXDBINTEGRITYOUTPUT" | grep -q "Database errors found"; then exit $MAILBOXDBINTEGRITYSTATUS elif echo "$MAILBOXDBINTEGRITYOUTPUT" | grep -q "Orphan accounts detected"; then echo "Orphan accounts detected. Continuing with the upgrade." fi fi break done fi fi } checkRecentBackup() { isInstalled zimbra-store if [ x$PKGINSTALLED != "x" ]; then if [ -x "bin/checkValidBackup" ]; then echo "Checking for a recent backup" `bin/checkValidBackup > /dev/null 2>&1` if [ $? != 0 ]; then echo "WARNING: Unable to find a full system backup started within the last" echo "24hrs. It is recommended to perform a full system backup and" echo "copy it to a safe location prior to performing an upgrade." echo "" if [ x$DEFAULTFILE = "x" ]; then while :; do askYN "Do you wish to continue without a backup?" "N" if [ $response = "no" ]; then askYN "Exit?" "N" if [ $response = "yes" ]; then echo "Exiting." exit 1 fi else break fi done else echo "Automated install detected...continuing." fi fi fi fi } checkCAKeyLength() { isInstalled "zimbra-ldap" if [ x$PKGINSTALLED != "x" ]; then openssl_cmd="" keyfile="/opt/zimbra/conf/ca/ca.key" if [[ -x "/opt/zimbra/common/bin/openssl" ]]; then openssl_cmd="/opt/zimbra/common/bin/openssl" else openssl_cmd=$(which openssl 2>/dev/null) fi if [[ -f "$keyfile" && -x "$openssl_cmd" ]]; then echo "Checking the keysize of $keyfile ..." key_length=$("$openssl_cmd" rsa -in "$keyfile" -noout -text 2>/dev/null | grep -oP 'Private-Key: \(\K\d+' | head -1) if [[ -n "$key_length" && "$key_length" -lt 2048 ]]; then echo "$keyfile has a key size of $key_length bits. The minimum key size is 2048. Please fix it to proceed with the upgrade." exit 1 fi fi fi } checkUbuntuRelease() { if [ -f "/etc/lsb-release" ]; then . /etc/lsb-release fi if [ x"$DEFAULTFILE" != "x" ]; then echo "Automated install detected...continuing." return fi if [ "x$DISTRIB_ID" = "xUbuntu" -a "x$DISTRIB_RELEASE" != "x12.04" -a "x$DISTRIB_RELEASE" != "x14.04" -a "x$DISTRIB_RELEASE" != "x16.04" -a "x$DISTRIB_RELEASE" != "x18.04" -a "x$DISTRIB_RELEASE" != "x20.04" -a "x$DISTRIB_RELEASE" != "x22.04" -a "x$DISTRIB_RELEASE" != "x24.04" ]; then echo "WARNING: ZCS is currently only supported on Ubuntu Server 12.04, 14.04, 16.04, 18.04, 20.04, 22.04 and 24.04 LTS." echo "You are attempting to install on $DISTRIB_DESCRIPTION which may not work." echo "Support will not be provided if you choose to continue." echo "" while :; do askYN "Do you wish to continue?" "N" if [ $response = "no" ]; then askYN "Exit?" "N" if [ $response = "yes" ]; then echo "Exiting." exit 1 fi else break fi done fi } checkVersionDowngrade() { if [ x"${ZM_CUR_MAJOR}" = "x" -o x"${ZM_CUR_MINOR}" = "x" -o x"${ZM_CUR_MICRO}" = "x" ]; then return fi if [ x"${ZM_INST_MAJOR}" = "x" -o x"${ZM_INST_MINOR}" = "x" -o x"${ZM_INST_MICRO}" = "x" ]; then return fi if [ ${ZM_CUR_MAJOR} -lt 7 ]; then echo "ERROR: You can only upgrade from ZCS 7.0 or later" exit 1 fi ZM_CUR_VERSION="${ZM_CUR_MAJOR}.${ZM_CUR_MINOR}.${ZM_CUR_MICRO}" ZM_INST_VERSION="${ZM_INST_MAJOR}.${ZM_INST_MINOR}.${ZM_INST_MICRO}" DOWNGRADE=0 if [ ${ZM_CUR_MAJOR} -gt ${ZM_INST_MAJOR} ]; then #echo "$ZM_CUR_VERSION is newer then $ZM_INST_VERSION MAJOR" DOWNGRADE=1 elif [ ${ZM_CUR_MAJOR} -eq ${ZM_INST_MAJOR} ]; then if [ ${ZM_CUR_MINOR} -gt ${ZM_INST_MINOR} ]; then #echo "$ZM_CUR_VERSION is newer then $ZM_INST_VERSION MINOR" DOWNGRADE=1 elif [ ${ZM_CUR_MINOR} -eq ${ZM_INST_MINOR} ]; then if [ ${ZM_CUR_MICRO} -gt ${ZM_INST_MICRO} ]; then #echo "$ZM_CUR_VERSION is newer then $ZM_INST_VERSION MICRO" DOWNGRADE=1 fi fi fi if [ $DOWNGRADE = 1 ]; then echo "Downgrading to version $ZM_INST_VERSION from $ZM_CUR_VERSION is not supported." exit 1 else echo "ZCS upgrade from $ZM_CUR_VERSION to $ZM_INST_VERSION will be performed." fi } checkRequired() { if [ -x "/usr/bin/getent" ]; then if ! /usr/bin/getent hosts 127.0.0.1 | perl -ne 'if (! m|^\d+\.\d+\.\d+\.\d+\s+localhost\s*| && ! m|^\d+\.\d+\.\d+\.\d+\s+localhost\.localdomain\s*|) { exit 11;}'; then cat< " echo "" echo " Where is the ip address of the host, " echo " is the FULLY QUALIFIED host name, and" echo " is the (optional) hostname-only portion" echo "" exit 1 fi fi GOOD="yes" # limitation of ext3 if [ -d "/opt/zimbra/db/data" ]; then echo "Checking current number of databases..." FS_TYPE=`df -T /opt/zimbra/db/data | awk '{ if (NR == 2) { print $2 } }'` if [ "${FS_TYPE}"x = "ext3"x ]; then DBCOUNT=`find /opt/zimbra/db/data -type d | wc -l | awk '{if ($NF-1 >= 31998) print $NF-1}'` if [ x"$DBCOUNT" != "x" ]; then echo "You have $DBCOUNT databases on an ext3 FileSystem, which is at" echo "or over the limit of 31998 databases. You will need to delete at" echo "least one database prior to upgrading or your upgrade will fail." echo "/opt/zimbra/db/data/test is a good candidate for removal." exit 1 fi fi fi checkCAKeyLength checkRecentBackup checkDatabaseIntegrity } checkRequiredSpace() { # /tmp must have 100MB # /opt/zimbra must have 5GB for fresh installs with zimbra-store # /opt/zimbra must have 500MB for upgrades GOOD=yes echo "Checking required space for zimbra-core" TMPKB=`df -Pk /tmp | tail -1 | awk '{print $4}'` AVAIL=$(($TMPKB / 1024)) if [ $AVAIL -lt 100 ]; then echo "/tmp must have at least 100MB of availble space to install." echo "${AVAIL}MB is not enough space to install ZCS." GOOD=no fi ZIMBRA=`df -Pk /opt/zimbra | tail -1 | awk '{print $4}'` if [ $UPGRADE = "yes" ]; then AVAIL=$(($ZIMBRA / 1024)) if [ $AVAIL -lt 500 ]; then echo "/opt/zimbra requires at least 500MB of space to upgrade." echo "${AVAIL}MB is not enough space to upgrade." GOOD=no fi fi isInstalled zimbra-store isToBeInstalled zimbra-store if [ "x$PKGINSTALLED" != "x" -o "x$PKGTOBEINSTALLED" != "x" ]; then echo "Checking space for zimbra-store" if [ $UPGRADE = "no" ]; then AVAIL=$(($ZIMBRA / 1048576)) if [ $AVAIL -lt 5 ]; then echo "/opt/zimbra requires at least 5GB of space to install." echo "${AVAIL}GB is not enough space to install." GOOD=no fi fi fi if [ $GOOD = "no" ]; then if [ x"$SKIPSPACECHECK" != "xyes" ]; then echo "" echo "Installation cancelled." echo "" exit 1 else echo "" echo "Installation will continue by request." echo "" fi fi } checkStoreRequirements() { if [[ $ONLYOFFICE_SELECTED == "yes" ]]; then return fi echo "Checking required packages for zimbra-store" GOOD="yes" if [ x"$ZMTYPE_INSTALLABLE" = "xNETWORK" ]; then for i in $STORE_PACKAGES; do #echo -n " $i..." isInstalled $i if [ "x$PKGINSTALLED" != "x" ]; then echo " FOUND: $PKGINSTALLED" else if [[ $ONLYOFFICE_SELECTED == "yes" && $i == libreoffice* ]]; then continue fi echo " MISSING: $i" GOOD="no" fi done fi if [ $GOOD = "no" ]; then echo "" echo "###WARNING###" echo "" echo "One or more suggested packages for zimbra-store are missing." echo "Some features may be disabled due to the missing package(s)." echo "" else echo "zimbra-store package check complete." fi } checkExistingInstall() { echo $PLATFORM | egrep -q "UBUNTU|DEBIAN" if [ $? = 0 ]; then if [ -L /opt -o -L /opt/zimbra ]; then echo "Installation cannot continue if either /opt or /opt/zimbra are symbolic links." exit 1 fi fi echo "Checking for existing installation..." for i in $OPTIONAL_PACKAGES; do isInstalled $i if [ x$PKGINSTALLED != "x" ]; then echo " $i...FOUND $PKGINSTALLED" INSTALLED_PACKAGES="$INSTALLED_PACKAGES $i" elif [ x$i != "xzimbra-qatest" ]; then echo " $i...NOT FOUND" fi done for i in $PACKAGES $CORE_PACKAGES; do echo -n " $i..." isInstalled $i if [ x"$PKGINSTALLED" != "x" ]; then echo "FOUND $PKGINSTALLED" if [ "$i" != "zimbra-memcached" ] && [ "$i" != "zimbra-license-daemon" ] && [ "$i" != "zimbra-onlyoffice" ]; then INSTALLED="yes" fi INSTALLED_PACKAGES="$INSTALLED_PACKAGES $i" else if [ x$i = "xzimbra-archiving" ]; then if [ -f "/opt/zimbra/lib/ext/zimbra_xmbxsearch/zimbra_xmbxsearch.jar" -a -f "/opt/zimbra/zimlets-network/zimbra_xmbxsearch.zip" ]; then echo "FOUND zimbra-cms" INSTALLED_PACKAGES="$INSTALLED_PACKAGES zimbra-archiving" else echo "NOT FOUND" fi else echo "NOT FOUND" fi fi done determineVersionType if [ $INSTALLED = "yes" ]; then verifyUpgrade verifyNGModulesInstalled fi verifyLicenseActivationServer verifyLicenseAvailable if [ $INSTALLED != "yes" ]; then checkUserInfo fi } determineVersionType() { isInstalled zimbra-core if [ x"$PKGINSTALLED" != "x" ]; then export ZMVERSION_CURRENT=`echo $PKGVERSION | sed s/^zimbra-core-//` if [ -f "/opt/zimbra/bin/zmbackupquery" ]; then ZMTYPE_CURRENT="NETWORK" else ZMTYPE_CURRENT="FOSS" fi ZM_CUR_MAJOR=$(perl -e '$v=$ENV{ZMVERSION_CURRENT}; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic) = $v =~ m/^(\d+)\.(\d+)\.(\d+)/; print "$maj\n"') ZM_CUR_MINOR=$(perl -e '$v=$ENV{ZMVERSION_CURRENT}; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic) = $v =~ m/^(\d+)\.(\d+)\.(\d+)/; print "$min\n"') ZM_CUR_MICRO=$(perl -e '$v=$ENV{ZMVERSION_CURRENT}; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic) = $v =~ m/^(\d+)\.(\d+)\.(\d+)/; print "$mic\n"') ZM_CUR_BUILD=$(perl -e '$v=$ENV{ZMVERSION_CURRENT}; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/^(\d+)\.(\d+)\.(\d+)\.(\w+)\.(\d+)/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/(\d+)\.(\d+)\.(\d+)_(\w+[^_])_(\d+)/ if ($rtype eq ""); print "$build\n";') fi # if we are removing the install we don't need the rest of the info if [ x"$UNINSTALL" = "xyes" ]; then return fi # need way to determine type for other package types ZMTYPE_INSTALLABLE="$(cat ${MYDIR}/.BUILD_TYPE)" ZM_INST_MAJOR=$(perl -e '$v=glob("packages/zimbra-core*"); $v =~ s/^packages\/zimbra-core[-_]//; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic) = $v =~ m/^(\d+)\.(\d+)\.(\d+)/; print "$maj\n"') ZM_INST_MINOR=$(perl -e '$v=glob("packages/zimbra-core*"); $v =~ s/^packages\/zimbra-core[-_]//; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic) = $v =~ m/^(\d+)\.(\d+)\.(\d+)/; print "$min\n"') ZM_INST_MICRO=$(perl -e '$v=glob("packages/zimbra-core*"); $v =~ s/^packages\/zimbra-core[-_]//; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic) = $v =~ m/^(\d+)\.(\d+)\.(\d+)/; print "$mic\n"') ZM_INST_RTYPE=$(perl -e '$v=glob("packages/zimbra-core*"); $v =~ s/^packages\/zimbra-core[-_]//; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/^(\d+)\.(\d+)\.(\d+)\.(\w+)\.(\d+)/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/(\d+)\.(\d+)\.(\d+)_(\w+[^_])_(\d+)/ if ($rtype eq ""); print "$rtype\n";') ZM_INST_BUILD=$(perl -e '$v=glob("packages/zimbra-core*"); $v =~ s/^packages\/zimbra-core[-_]//; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/^(\d+)\.(\d+)\.(\d+)\.(\w+)\.(\d+)/; ($maj,$min,$mic,$rtype,$build) = $v =~ m/(\d+)\.(\d+)\.(\d+)_(\w+[^_])_(\d+)/ if ($rtype eq ""); print "$build\n";') if [ x"$AUTOINSTALL" = "xyes" ]; then return fi #echo "TYPE: CURRENT: $ZMTYPE_CURRENT INSTALLABLE: $ZMTYPE_INSTALLABLE" #echo "VERSION: CURRENT: $ZM_CUR_MAJOR INSTALLABLE: $ZM_INST_MAJOR" checkVersionDowngrade if [ x"$ZMTYPE_CURRENT" = "xNETWORK" ] && [ x"$ZMTYPE_INSTALLABLE" = "xFOSS" ]; then echo "Warning: You are about to upgrade from the Network Edition to the" echo "Open Source Edition. This will remove all Network features, including" echo "Attachment Searching, Zimbra Mobile, Backup/Restore, and support for the " echo "Zimbra Connector for Outlook." while :; do askYN "Do you wish to continue?" "N" if [ $response = "no" ]; then askYN "Exit?" "N" if [ $response = "yes" ]; then echo "Exiting." exit 1 fi else break fi done fi if [ x"$ZMTYPE_CURRENT" = "xNETWORK" ]; then echo $ZM_INST_RTYPE | grep -v GA$ > /dev/null 2>&1 if [ $? = 0 ]; then if [ ${ZM_CUR_MAJOR} -lt ${ZM_INST_MAJOR} ]; then echo "This is a Network Edition ${ZM_INST_RTYPE} build and is not intended for production." if [ x"$BETA_SUPPORT" = "x" ]; then echo "Upgrades from $ZMVERSION_CURRENT are not supported." exit 1 else echo "Support for developer versions of ZCS maybe limited to bugzilla and Zimbra forums." #echo "Installing non-GA versions in production is not recommended." while :; do askYN "Do you wish to continue?" "N" if [ $response = "no" ]; then askYN "Exit?" "N" if [ $response = "yes" ]; then echo "Exiting." exit 1 fi else break fi done fi fi fi fi } verifyUpgrade() { if [ x"$UNINSTALL" = "xyes" ]; then return fi if [ ${ZM_CUR_MAJOR} -lt 8 ] || [ ${ZM_CUR_MAJOR} -eq 8 -a ${ZM_CUR_MINOR} -lt 7 ]; then if [ -x "bin/checkService.pl" ]; then echo "Checking for existing proxy service in your environment" # echo "Running bin/checkService.pl -s proxy" if [ ${ZM_CUR_MAJOR} -lt 8 ]; then `bin/checkService.pl -s imapproxy` else `bin/checkService.pl -s proxy` fi serviceProxyRC=$?; if [ "$serviceProxyRC" != 0 ]; then if [ "$serviceProxyRC" = 2 ]; then echo "Error: No proxy detected in your environment. Proxy is required for ZCS 8.7+." echo "See https://wiki.zimbra.com/wiki/Enabling_Zimbra_Proxy for details on installing proxy." else echo "Error: Unable to contact the LDAP server." exit 1 fi fi echo "Checking for existing memcached service in your environment" # echo "Running bin/checkService.pl -s memcached" `bin/checkService.pl -s memcached` serviceMemcachedRC=$?; if [ "$serviceMemcachedRC" != 0 ]; then if [ "$serviceMemcachedRC" = 2 ]; then echo "Error: No memcached detected in your environment. Memcached is required for ZCS 8.7+." echo "See https://wiki.zimbra.com/wiki/Enabling_Zimbra_Memcached for details on installing memcached." else echo "Error: Unable to contact the LDAP server." exit 1 fi fi fi if [ "$serviceProxyRC" != 0 ] || [ "$serviceMemcachedRC" != 0 ]; then echo "Proxy and Memcached services must exist. Exiting..." exit 1 fi fi if [ x"$SKIP_UPGRADE_CHECK" = "xyes" ]; then return fi # sometimes we just don't want to check if [ x"$AUTOINSTALL" = "xyes" ] || [ x"$SOFTWAREONLY" = "xyes" ]; then return fi isInstalled "zimbra-ldap" LDAP_INSTALLED=$PKGINSTALLED if [ "x$LDAP_INSTALLED" != "x" ]; then runAsZimbra "ldap start" fi isInstalled "zimbra-store" STORE_INSTALLED=$PKGINSTALLED if [ "x$LDAP_INSTALLED" != "x" ] || [ "x$STORE_INSTALLED" != "x" ]; then # Upgrade tests specific to NE only if [ x"$ZMTYPE_CURRENT" = "xNETWORK" ] && [ x"$ZMTYPE_INSTALLABLE" = "xNETWORK" ]; then if [ x"$SKIP_ACTIVATION_CHECK" = "xno" ]; then if [ -x "bin/checkLicense.pl" ]; then echo "Validating whether an existing license is expired or not and checking if it qualifies for an upgrade" echo $HOSTNAME | egrep -qe 'eng.zimbra.com$|lab.zimbra.com$|zimbradev.com$' > /dev/null 2>&1 if [ $? = 0 ]; then bin/checkLicense.pl -i -uv $ZM_INST_VERSION -cv $ZM_CUR_VERSION else bin/checkLicense.pl -uv $ZM_INST_VERSION -cv $ZM_CUR_VERSION fi licenseRC=$?; if [ $licenseRC != 0 ]; then if [ $licenseRC = 6 ]; then echo "Error: Unable to bind to LDAP" exit 1 elif [ $licenseRC = 5 ]; then echo "Error: Unable to execute startTLS with LDAP" exit 1 elif [ $licenseRC = 4 ]; then echo "Error: Unable to connect to LDAP" exit 1 elif [ $licenseRC = 3 ]; then echo "Error: No upgrade version supplied" exit 1 elif [ $licenseRC = 2 ]; then echo "Error: license key not found" exit 1 elif [ $licenseRC = 7 ]; then echo "Error: The license key should be an alphanumeric string of 18-24 characters without any special characters" exit 1 elif [ $licenseRC = 1 ]; then echo "Error: License is expired or not authorized for upgrade or cannot be upgraded." echo " Aborting upgrade" exit 1 else echo "Unknown Error. It should be impossible to reach this statement." exit 1 fi else echo "License is valid and supports this upgrade. Continuing." fi fi fi fi fi # Upgrade tests applicable to everyone echo "Validating ldap configuration" isInstalled "zimbra-ldap" LDAP_OPT="" if [ x$PKGINSTALLED != "x" ]; then LDAP_OPT="-l" fi `bin/zmValidateLdap.pl --vmajor ${ZM_CUR_MAJOR} --vminor ${ZM_CUR_MINOR} --vmicro ${ZM_CUR_MICRO} \ --umajor ${ZM_INST_MAJOR} --uminor ${ZM_INST_MINOR} --umicro ${ZM_INST_MICRO} ${LDAP_OPT} >/dev/null` ldapRC=$?; if [ $ldapRC != 0 ]; then if [ $ldapRC = 1 ]; then echo "Error: Unable to create a successful TLS connection to the ldap masters." echo " Fix cert configuration prior to upgrading." exit 1 elif [ $ldapRC = 2 ]; then echo "Error: Unable to bind to the LDAP server as the root LDAP user." echo " This is required to upgrade." exit 1 elif [ $ldapRC = 3 ]; then echo "Error: Unable to bind to the LDAP server as the zimbra LDAP user." echo " This is required to upgrade." exit 1 elif [ $ldapRC = 4 ]; then echo "Error: Unable to search LDAP server as the zimbra LDAP user." echo " This is required to upgrade." exit 1 elif [ $ldapRC = 5 ]; then echo "Error: One or more LDAP master servers has not yet been upgraded." echo " It is required for all LDAP master node(s) to be upgraded first." exit 1 else echo "Unknown Error: It should be impossible to reach this statement." exit 1 fi else echo "LDAP validation succeeded. Continuing." fi } verifyNGModulesInstalled() { if [ x"$SKIP_NG_CHECK" = "xyes" ] || [ x"$UNINSTALL" = "xyes" ]; then return fi NG_INSTALLED="no" for i in $ZEXTRAS_PACKAGES; do isInstalled $i if [ x"$PKGINSTALLED" != "x" ]; then NG_INSTALLED="yes" break fi done if [ $NG_INSTALLED = "yes" ]; then echo -e "\e[1;31m NG Modules detected on this system. If you continue with this upgrade, NG module packages and the associated data will be deleted. \033[0m" echo -e "\e[1;31m If you want to preserve NG data, consider migrating or a rolling upgrade strategy for upgrading your system. \033[0m" echo -e "\e[1;31m For more information, please contact Zimbra Support. \033[0m" echo -e "\e[1;31m If you still want to continue, start upgrade using --skip-ng-check \033[0m" exit 1 fi } verifyLicenseActivationServer() { if [ x"$SKIP_ACTIVATION_CHECK" = "xyes" -o x"$SKIP_UPGRADE_CHECK" = "xyes" ]; then return fi # sometimes we just don't want to check if [ x"$AUTOINSTALL" = "xyes" ] || [ x"$UNINSTALL" = "xyes" ] || [ x"$SOFTWAREONLY" = "xyes" ]; then return fi # make sure this is an upgrade isInstalled zimbra-store if [ x$PKGINSTALLED = "x" ]; then return fi # make sure the current version we are trying to install is a NE version if [ x"$ZMTYPE_INSTALLABLE" != "xNETWORK" ]; then return fi # make sure we can contact the activation server for automated activation echo $HOSTNAME | egrep -qe 'zimbra.com$|zimbradev.com$' > /dev/null 2>&1 if [ $? = 0 ]; then url='https://zimbra-stage-license.eng.zimbra.com/zimbraLicensePortal/public/activation?action=test' else url='https://license.zimbra.com/zimbraLicensePortal/public/activation?action=test' fi cmd=$(which curl 2>/dev/null) if [ -x "$cmd" ]; then output=$($cmd --connect-timeout 5 -s -f $url) if [ $? != 0 ]; then output=$($cmd -k --connect-timeout 5 -s -f $url) if [ $? != 0 ]; then activationWarning else return fi else return fi fi cmd=$(which wget 2>/dev/null) if [ -x "$cmd" ]; then output=$($cmd --tries 1 -T 5 -q -O /tmp/zmlicense.tmp $url) if [ $? != 0 ]; then output=$($cmd --no-check-certificate --tries 1 -T 5 -q -O /tmp/zmlicense.tmp $url) if [ $? != 0 ]; then activationWarning else return fi activationWarning else return fi fi } activationWarning() { echo "ERROR: Unable to reach the Zimbra License Activation Server." echo "" echo "License Activation is required when upgrading to ZCS 7 or later." echo "" echo "The ZCS Network upgrade will automatically attempt to activate the" echo "current license as long as the activation server can be contacted." echo "" echo "A manual license activation key can be obtained by either visiting" echo "the Zimbra support portal or contacting Zimbra support or sales." echo "" exit 1; } verifyLicenseAvailable() { if [ x"$AUTOINSTALL" = "xyes" ] || [ x"$UNINSTALL" = "xyes" ] || [ x"$SOFTWAREONLY" = "xyes" ]; then return fi isInstalled zimbra-store if [ x$PKGINSTALLED = "x" ]; then return fi # need to finish for other native packagers if [ "$(cat ${MYDIR}/.BUILD_TYPE)" != "NETWORK" ]; then return fi echo "Checking for available license..." # use the tool if it exists if [ -f "/opt/zimbra/bin/zmlicense" ]; then licenseCheck=`su - zimbra -c "zmlicense -c" 2> /dev/null` if [ "${ZM_CUR_MAJOR}" -gt "10" ] || [ "${ZM_CUR_MAJOR}" -eq "10" -a "${ZM_CUR_MINOR}" -ge "1" ]; then licensedUsers=$(su - zimbra -c "zmprov gcf zimbraNetworkRealtimeActivation 2>/dev/null | grep -o '\"licenseFeatureDetails\":{[^}]*}' | grep -o '\"totalLimit\":\"[^\"]*' | awk -F '\"' '{print \$4}'") licenseValidUntil=$(su - zimbra -c "zmprov gcf zimbraNetworkRealtimeActivation 2>/dev/null | grep -o '\"licenseActivationDetails\":{[^}]*}' | grep -o '\"ValidUntil\":[^,}]*' | sed 's/\"ValidUntil\"://; s/\"//g'") licenseType=$(su - zimbra -c "zmprov gcf zimbraNetworkRealtimeActivation 2>/dev/null | grep -o '\"licenseActivationDetails\":{[^}]*}' | grep -o '\"InstallType\":\"[^\"]*' | awk -F '\"' '{print \$4}'") else licensedUsers=`su - zimbra -c "zmlicense -p | grep ^AccountsLimit | sed -e 's/AccountsLimit=//'" 2> /dev/null` licenseValidUntil=`su - zimbra -c "zmlicense -p | grep ^ValidUntil= | sed -e 's/ValidUntil=//'" 2> /dev/null` licenseType=`su - zimbra -c "zmlicense -p | grep ^InstallType= | sed -e 's/InstallType=//'" 2> /dev/null` fi fi # parse files if license tool wasn't there or didn't return a valid license if [ x"$licenseCheck" = "xlicense not installed" ] || [ x"$licenseCheck" = "x" ] || [[ "$licenseCheck" =~ "License is not activated" ]]; then if [ -f "/opt/zimbra/conf/ZCSLicense.xml" ]; then licenseCheck="license is OK" licensedUsers=`cat /opt/zimbra/conf/ZCSLicense.xml | grep AccountsLimit | head -1 | awk '{print $3}' | awk -F= '{print $2}' | awk -F\" '{print $2}'` licenseValidUntil=`cat /opt/zimbra/conf/ZCSLicense.xml | awk -F\" '{ if ($2 ~ /^ValidUntil$/) {print $4 } }'` licenseType=`cat /opt/zimbra/conf/ZCSLicense.xml | awk -F\" '{ if ($2 ~ /^InstallType$/) {print $4 } }'` elif [ -f "/opt/zimbra/conf/ZCSLicense-Trial.xml" ]; then licenseCheck="license is OK" licensedUsers=`cat /opt/zimbra/conf/ZCSLicense-Trial.xml | grep AccountsLimit | head -1 | awk '{print $3}' | awk -F= '{print $2}' | awk -F\" '{print $2}'` licenseValidUntil=`cat /opt/zimbra/conf/ZCSLicense-Trial.xml | awk -F\" '{ if ($2 ~ /^ValidUntil$/) {print $4 } }'` licenseType=`cat /opt/zimbra/conf/ZCSLicense-Trial.xml | awk -F\" '{ if ($2 ~ /^InstallType$/) {print $4 } }'` else echo "WARNING: The ZCS Network upgrade requires a valid license to be installed." echo "" echo "New customers wanting to purchase or obtain a trial license" echo "should contact Zimbra sales. Contact information for Zimbra is" echo "located at http://www.zimbra.com/about/contact_us.html" echo "Existing customers can obtain an updated license file via the" echo "Zimbra Support page located at http://www.zimbra.com/support." echo "" fi fi if [ "${ZM_CUR_MAJOR}" -gt "10" ] || [ "${ZM_CUR_MAJOR}" -eq "10" -a "${ZM_CUR_MINOR}" -ge "1" ]; then now=`date -u "+%Y-%m-%d"` else now=`date -u "+%Y%m%d%H%M%SZ"` fi if [ \( x"$licenseValidUntil" \< x"$now" -o x"$licenseValidUntil" == x"$now" \) -a x"$ZMTYPE_INSTALLABLE" == x"NETWORK" ]; then if [ x"$licenseType" == x"perpetual" ]; then echo "" echo "ERROR: The ZCS Network upgrade requires a previously installed license" echo "to be valid and not expired." echo "" echo "The upgrade cannot occur with an expired perpetual license. In order" echo "to perform an upgrade, you will need to have a valid support contract" echo "in place." echo "" echo "Your system has not been modified." echo "" exit 1; else echo "" echo "WARNING: The ZCS Network upgrade requires a previously installed license" echo "to be valid and not expired." echo "" echo "The upgrade can continue, but there will be some loss of functionality." echo "" while :; do askYN "Do you wish to continue? " "N" if [ $response == "no" ]; then askYN "Exit?" "N" if [ $response == "yes" ]; then echo "" echo "Your system has not been modified." echo"" exit 1; fi else break fi done fi fi if [ x"$licensedUsers" = "x" ]; then licensedUsers=0 fi # return immediately if we have an unlimited license if [ "$licensedUsers" = "-1" ]; then return fi # Check for licensed user count and warn if necessary oldUserCheck=0 if [ ${ZM_CUR_MAJOR} -eq 6 -a ${ZM_CUR_MICRO} -lt 8 ]; then userProvCommand="zmprov -l gaa 2> /dev/null | wc -l" oldUserCheck=1 else userProvCommand="zmprov -l cto userAccounts 2> /dev/null" fi # Make sure zmprov is responsive and able to talk to LDAP before we do anything for real zmprovTest="zmprov -l gac 2> /dev/null > /dev/null" su - zimbra -c "$zmprovTest" zmprovTestRC=$? if [ $zmprovTestRC -eq 0 ]; then su - zimbra -c "$zmprovTest" zmprovTestRC=$? fi if [ $zmprovTestRC -ne 0 ]; then echo "" echo "Warning: Unable to determine the number of users on this system via zmprov command." echo "Please make sure LDAP services are running." echo "" fi # Passed check to make sure zmprov and LDAP are working. Now let's get a real count. numCurrentUsers=-1; if [ $zmprovTestRC -eq 0 ]; then numCurrentUsers=`su - zimbra -c "$userProvCommand"`; numUsersRC=$? if [ $numUsersRC -ne 0 ]; then numCurrentUsers=`su - zimbra -c "$userProvCommand"`; numUsersRC=$? fi fi # Unable to determine the number of current users if [ "$numCurrentUsers"x = "x" ]; then numCurrentUsers=-1; echo "" echo "Warning: Unable to determine the number of users on this system via zmprov command." echo "Please make sure LDAP services are running." echo "" fi if [ $oldUserCheck -eq 1 ]; then numCurrentUsers=`expr $numCurrentUsers - 3` fi if [ $numCurrentUsers -gt 0 ]; then echo "Current Users=$numCurrentUsers Licensed Users=$licensedUsers" fi if [ $numCurrentUsers -lt 0 ]; then echo "Warning: Could not determine the number of users on this system." echo "If you exceed the number of licensed users ($licensedUsers) then you will" echo "not be able to create new users." while :; do askYN "Do you wish to continue?" "N" if [ $response = "no" ]; then askYN "Exit?" "N" if [ $response = "yes" ]; then echo "Exiting. Please install a valid license and rerun." exit 1 fi else break fi done elif [ $numUsersRC -ne 0 ] || [ $numCurrentUsers -gt $licensedUsers ]; then echo "Warning: The number of users on this system ($numCurrentUsers) exceeds the licensed number" echo "($licensedUsers). You may continue with the upgrade, but you will not be able to create" echo "new users. Also, initialization of the Document feature will fail. If you " echo "later wish to use the Documents feature you'll need to resolve the licensing " echo "issues and then run a separate script available from support to initialize the " echo "Documents feature. " while :; do askYN "Do you wish to continue?" "N" if [ $response = "no" ]; then askYN "Exit?" "N" if [ $response = "yes" ]; then echo "Exiting. Please install a valid license and rerun." exit 1 fi else break fi done else # valid license and user count return fi } checkUserInfo() { #Verify that the zimbra user either: # Doesn't exist OR # Exists with: # home: /opt/zimbra # shell: bash id zimbra > /dev/null 2>&1 if [ $? -ne 0 ]; then return fi if [ -x /usr/bin/getent ] then ZH=`getent passwd zimbra | awk -F: '{ print $6 }'` ZS=`getent passwd zimbra | awk -F: '{ print $7 }' | sed -e s'|.*/||'` else ZH=`awk -F: '/^zimbra:/ {print $6}' /etc/passwd` ZS=`awk -F: '/^zimbra:/ {print $7}' /etc/passwd | sed -e s'|.*/||'` fi if [ x$ZH != "x/opt/zimbra" ]; then echo "Error - zimbra user exists with incorrect home directory: $ZH" echo "Exiting" exit 1 fi if [ x$ZS != "xbash" ]; then echo "Error - zimbra user exists with incorrect shell: $ZS" echo "Exiting" exit 1 fi } runAsZimbra() { # echo "Running as zimbra: $1" echo "COMMAND: $1" >> $LOGFILE 2>&1 su - zimbra -c "$1" >> $LOGFILE 2>&1 } shutDownSystem() { runAsZimbra "zmcontrol shutdown" isInstalled "zimbra-license-daemon" if [ x$PKGINSTALLED != "x" ]; then [ -x "/opt/zimbra/bin/zmlicensectl" ] && runAsZimbra "/opt/zimbra/bin/zmlicensectl --service stop" fi # stop all zimbra process that may have been orphaned local OS=$(uname -s | tr A-Z a-z) if [ x"$OS" = "xlinux" ]; then if [ -x /bin/ps -a -x /usr/bin/awk -a -x /usr/bin/xargs ]; then /bin/ps -eFw | /usr/bin/awk '{ if ($1 == "zimbra" && $3 == "1") print $2 }' | /usr/bin/xargs kill -9 > /dev/null 2>&1 fi fi } getRunningSchemaVersion() { RUNNINGSCHEMAVERSION=`su - zimbra -c "echo \"select value from config where name='db.version';\" | mysql zimbra --skip-column-names"` if [ "x$RUNNINGSCHEMAVERSION" = "x" ]; then RUNNINGSCHEMAVERSION=0 fi } getPackageSchemaVersion() { PACKAGESCHEMAVERSION=`cat data/versions-init.sql | grep db.version | sed -e s/[^0-9]//g` } getRunningIndexVersion() { RUNNINGINDEXVERSION=`su - zimbra -c "echo \"select value from config where name='index.version';\" | mysql zimbra --skip-column-names"` if [ "x$RUNNINGINDEXVERSION" = "x" ]; then RUNNINGINDEXVERSION=0 fi } getPackageIndexVersion() { PACKAGEINDEXVERSION=`cat data/versions-init.sql | grep index.version | sed -e s/[^0-9]//g` } checkVersionMatches() { VERSIONMATCH="yes" # This bombs when mysql isn't around, and was a really bad # idea, anyway return getRunningSchemaVersion getPackageSchemaVersion getRunningIndexVersion getPackageIndexVersion if [ $RUNNINGSCHEMAVERSION != $PACKAGESCHEMAVERSION ]; then VERSIONMATCH="no" return fi if [ $RUNNINGINDEXVERSION != $PACKAGEINDEXVERSION ]; then VERSIONMATCH="no" return fi } setRemove() { if [ $INSTALLED = "yes" -o $FORCE_UPGRADE = "yes" ]; then checkVersionMatches if [ $INSTALLED = "yes" ]; then echo "" echo "The Zimbra Collaboration Server appears to already be installed." if [ $VERSIONMATCH = "yes" ]; then echo "It can be upgraded with no effect on existing accounts," echo "or the current installation can be completely removed prior" echo "to installation for a clean install." else echo "" echo "###WARNING###" if [ $RUNNINGSCHEMAVERSION -eq 0 -o $RUNNINGINDEXVERSION -eq 0 ]; then echo "" echo "It appears that the mysql server is not running" echo "This may be the cause of the problem" echo "" fi echo "There is a mismatch in the versions of the installed schema" echo "or index and the version included in this package" echo "If you wish to upgrade, please correct this problem first." askYN "Exit now?" "Y" if [ $response = "yes" ]; then exit 1; fi fi fi while :; do UPGRADE="yes" if [ $FORCE_UPGRADE = "yes" -o $VERSIONMATCH = "yes" ]; then askYN "Do you wish to upgrade?" "Y" else UPGRADE="no" response="no" fi if [ $response = "no" ]; then askYN "Exit now?" "Y" if [ $response = "yes" ]; then exit 1; fi echo "" echo $INSTALLED_PACKAGES | grep zimbra-ldap > /dev/null 2>&1 if [ $? = 0 ]; then echo "*** WARNING - you are about to delete all existing users and mail" else echo $INSTALLED_PACKAGES | grep zimbra-store > /dev/null 2>&1 if [ $? = 0 ]; then echo "*** WARNING - you are about to delete users and mail hosted on this server" else REMOVE="yes" UPGRADE="no" break fi fi askYN "Delete users/mail?" "N" if [ $response = "yes" ]; then REMOVE="yes" UPGRADE="no" break fi else if [ $FORCE_UPGRADE = "no" ]; then # Check for a history file - create it if it's not there isInstalled "zimbra-core" if [ ! -f "/opt/zimbra/.install_history" ]; then cat > /opt/zimbra/.install_history << EOF 0000000000: INSTALL SESSION START 0000000000: INSTALLED $PKGVERSION 0000000000: INSTALL SESSION COMPLETE 0000000000: CONFIG SESSION START 0000000000: CONFIGURED BEGIN 0000000000: CONFIGURED END 0000000000: CONFIG SESSION COMPLETE EOF fi fi break fi done else # REMOVE = yes for non installed systems, to clean up /opt/zimbra DETECTDIRS="db bin/zmcontrol redolog index store conf/localconfig.xml data" for i in $DETECTDIRS; do if [ -e "/opt/zimbra/$i" ]; then INSTALLED="yes" fi done if [ x$INSTALLED = "xyes" ]; then echo "" echo "The Zimbra Collaboration Server does not appear to be installed," echo "yet there appears to be a ZCS directory structure in /opt/zimbra." askYN "Would you like to delete /opt/zimbra before installing?" "N" REMOVE="$response" else REMOVE="yes" fi fi } setDefaultsFromExistingConfig() { if [ ! -f "$SAVEDIR/config.save" ]; then return fi echo "" echo "Setting defaults from saved config in $SAVEDIR/config.save" source $SAVEDIR/config.save HOSTNAME=${zimbra_server_hostname} LDAPHOST=${ldap_host} LDAPPORT=${ldap_port} SNMPTRAPHOST=${snmp_trap_host:-$SNMPTRAPHOST} SMTPSOURCE=${smtp_source:-$SMTPSOURCE} SMTPDEST=${smtp_destination:-$SMTPDEST} SNMPNOTIFY=${snmp_notify:-0} SMTPNOTIFY=${smtp_notify:-0} LDAPROOTPW=${ldap_root_password} LDAPZIMBRAPW=${zimbra_ldap_password} LDAPPOSTPW=${ldap_postfix_password} LDAPREPPW=${ldap_replication_password} LDAPAMAVISPW=${ldap_amavis_password} LDAPNGINXPW=${ldap_nginx_password} echo " HOSTNAME=${zimbra_server_hostname}" echo " LDAPHOST=${ldap_host}" echo " LDAPPORT=${ldap_port}" echo " SNMPTRAPHOST=${snmp_trap_host}" echo " SMTPSOURCE=${smtp_source}" echo " SMTPDEST=${smtp_destination}" echo " SNMPNOTIFY=${snmp_notify:-0}" echo " SMTPNOTIFY=${smtp_notify:-0}" echo " LDAPROOTPW=*" echo " LDAPZIMBRAPW=*" echo " LDAPPOSTPW=*" echo " LDAPREPPW=*" echo " LDAPAMAVISPW=*" echo " LDAPNGINXPW=*" } restoreExistingConfig() { if [ -d $RESTORECONFIG ]; then RF="$RESTORECONFIG/localconfig.xml" fi if [ -f $RF ]; then echo -n "Restoring existing configuration file from $RF..." cp -f $RF /opt/zimbra/conf/localconfig.xml echo "done" fi } # deprecated by the move of zimlets to /opt/zimbra/zimlets-deployed which isn't removed on upgrade restoreZimlets() { if [ -d $SAVEDIR/zimlet -a -d /opt/zimbra/mailboxd/webapps/service ]; then cp -rf $SAVEDIR/zimlet /opt/zimbra/mailboxd/webapps/service/ chown -R zimbra:zimbra /opt/zimbra/mailboxd/webapps/service/zimlet chmod 775 /opt/zimbra/mailboxd/webapps/service/zimlet fi } restoreCerts() { if [ -f "$SAVEDIR/keystore" -a -d "/opt/zimbra/jetty/etc" ]; then cp $SAVEDIR/keystore /opt/zimbra/jetty/etc/keystore chown zimbra:zimbra /opt/zimbra/jetty/etc/keystore chmod u+w /opt/zimbra/jetty/etc/keystore elif [ -f "$SAVEDIR/keystore" -a -d "/opt/zimbra/conf" ]; then cp $SAVEDIR/keystore /opt/zimbra/conf/keystore chown zimbra:zimbra /opt/zimbra/conf/keystore chmod u+w /opt/zimbra/conf/keystore fi if [ -f "$SAVEDIR/smtpd.key" ]; then cp $SAVEDIR/smtpd.key /opt/zimbra/conf/smtpd.key chown zimbra:zimbra /opt/zimbra/conf/smtpd.key fi if [ -f "$SAVEDIR/smtpd.crt" ]; then cp $SAVEDIR/smtpd.crt /opt/zimbra/conf/smtpd.crt chown zimbra:zimbra /opt/zimbra/conf/smtpd.crt fi if [ -f "$SAVEDIR/slapd.crt" ]; then cp $SAVEDIR/slapd.crt /opt/zimbra/conf/slapd.crt chown zimbra:zimbra /opt/zimbra/conf/slapd.crt fi if [ -f "$SAVEDIR/nginx.key" ]; then cp $SAVEDIR/nginx.key /opt/zimbra/conf/nginx.key chown zimbra:zimbra /opt/zimbra/conf/nginx.key fi if [ -f "$SAVEDIR/nginx.crt" ]; then cp $SAVEDIR/nginx.crt /opt/zimbra/conf/nginx.crt chown zimbra:zimbra /opt/zimbra/conf/nginx.crt fi mkdir -p /opt/zimbra/conf/ca if [ -f "$SAVEDIR/ca.key" ]; then cp $SAVEDIR/ca.key /opt/zimbra/conf/ca/ca.key chown zimbra:zimbra /opt/zimbra/conf/ca/ca.key fi if [ -f "$SAVEDIR/ca.pem" ]; then cp $SAVEDIR/ca.pem /opt/zimbra/conf/ca/ca.pem chown zimbra:zimbra /opt/zimbra/conf/ca/ca.pem fi if [ -f "/opt/zimbra/jetty/etc/keystore" ]; then chown zimbra:zimbra /opt/zimbra/jetty/etc/keystore chmod u+w /opt/zimbra/jetty/etc/keystore fi } saveExistingConfig() { if [ $UPGRADE != "yes" -o $FORCE_UPGRADE = "yes" ]; then return fi echo "" echo "Saving existing configuration file to $SAVEDIR" # Since the location to java has changed, we need to fix localconfig.xml before we save the configuration # and start the upgrade process if [ -x "/opt/zimbra/bin/zmlocalconfig" ]; then runAsZimbra "zmlocalconfig -e zimbra_java_home=/opt/zimbra/common/lib/jvm/java" runAsZimbra "zmlocalconfig -e mailboxd_truststore=/opt/zimbra/common/lib/jvm/java/lib/security/cacerts" fi if [ ! -d "$SAVEDIR" ]; then mkdir -p $SAVEDIR fi # make copies of existing save files for f in localconfig.xml config.save keystore cacerts smtpd.key smtpd.crt slapd.key slapd.crt ca.key backup.save; do if [ -f "${SAVEDIR}/${f}" ]; then for (( i=0 ;; i++ )); do if [ ! -f "${SAVEDIR}/${ZMVERSION_CURRENT}/${i}/${f}" ]; then mkdir -p ${SAVEDIR}/${ZMVERSION_CURRENT}/${i} 2> /dev/null mv -f "${SAVEDIR}/${f}" "${SAVEDIR}/${ZMVERSION_CURRENT}/${i}/${f}" break fi done fi done # yes, it needs massaging to be fed back in... if [ -x "/opt/zimbra/bin/zmlocalconfig" ]; then runAsZimbra "zmlocalconfig -s | sed -e \"s/ = \(.*\)/=\'\1\'/\" > $SAVEDIR/config.save" fi if [ -f "/opt/zimbra/conf/localconfig.xml" ]; then cp -f /opt/zimbra/conf/localconfig.xml $SAVEDIR/localconfig.xml fi if [ -f "/opt/zimbra/common/lib/jvm/java/lib/security/cacerts" ]; then cp -f /opt/zimbra/common/lib/jvm/java/lib/security/cacerts $SAVEDIR elif [ -f "/opt/zimbra/java/lib/security/cacerts" ]; then cp -f /opt/zimbra/java/lib/security/cacerts $SAVEDIR fi if [ -f "/opt/zimbra/jetty/etc/keystore" ]; then cp -f /opt/zimbra/jetty/etc/keystore $SAVEDIR fi if [ -f "/opt/zimbra/conf/smtpd.key" ]; then cp -f /opt/zimbra/conf/smtpd.key $SAVEDIR fi if [ -f "/opt/zimbra/conf/smtpd.crt" ]; then cp -f /opt/zimbra/conf/smtpd.crt $SAVEDIR fi if [ -f "/opt/zimbra/conf/slapd.key" ]; then cp -f /opt/zimbra/conf/slapd.key $SAVEDIR fi if [ -f "/opt/zimbra/conf/slapd.crt" ]; then cp -f /opt/zimbra/conf/slapd.crt $SAVEDIR fi if [ -f "/opt/zimbra/conf/nginx.key" ]; then cp -f /opt/zimbra/conf/nginx.key $SAVEDIR fi if [ -f "/opt/zimbra/conf/nginx.crt" ]; then cp -f /opt/zimbra/conf/nginx.crt $SAVEDIR fi if [ -f "/opt/zimbra/conf/ca/ca.key" ]; then cp -f /opt/zimbra/conf/ca/ca.key $SAVEDIR fi if [ -f "/opt/zimbra/conf/ca/ca.pem" ]; then cp -f /opt/zimbra/conf/ca/ca.pem $SAVEDIR fi if [ -d "/opt/zimbra/mailboxd/webapps/service/zimlet" ]; then cp -rf /opt/zimbra/mailboxd/webapps/service/zimlet $SAVEDIR fi if [ -x /opt/zimbra/bin/zmschedulebackup ]; then runAsZimbra "zmschedulebackup -s > $SAVEDIR/backup.save" fi if [ -d /opt/zimbra/wiki ]; then cp -rf /opt/zimbra/wiki $SAVEDIR fi if [ -f "/opt/zimbra/.enable_replica" ]; then rm -f /opt/zimbra/.enable_replica fi if [ -f /opt/zimbra/data/ldap/config/cn\=config.ldif ]; then if [ -f /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{2\}mdb/olcOverlay\=*syncprov.ldif ]; then touch /opt/zimbra/.enable_replica fi fi } findUbuntuExternalPackageDependencies() { # Handle external packages like logwatch, mailutils depends on zimbra-mta. if [ $INSTALLED = "yes" -a $ISUBUNTU = "true" ]; then RABBITMQINSTALLED="no" isInstalled "zimbra-onlyoffice" if [ x$PKGINSTALLED != "x" ]; then RABBITMQINSTALLED="yes" fi $PACKAGERMSIMULATE $INSTALLED_PACKAGES > /dev/null 2>&1 if [ $? -ne 0 ]; then EXTPACKAGESTMP=`$PACKAGERMSIMULATE $INSTALLED_PACKAGES 2>&1 | grep " depends on " | cut -d' ' -f2 | grep -v zimbra` for p in $EXTPACKAGESTMP; do EXTPACKAGES="$p $EXTPACKAGES" done if [ -z "$EXTPACKAGES" ]; then echo "External package dependencies not found" else echo "External package dependencies found: $EXTPACKAGES" $PACKAGERMSIMULATE $INSTALLED_PACKAGES $EXTPACKAGES >> $LOGFILE 2>&1 if [ $? -eq 0 ]; then while :; do askYN "$EXTPACKAGES package[s] will be removed. Continue?" "N" if [ $response = "no" ]; then askYN "Exit?" "N" if [ $response = "yes" ]; then removeErrorMessage fi else break fi done fi fi fi fi } removeErrorMessage() { echo "Can not remove packages. Check $LOGFILE for details." echo "Exiting - the system is unchanged" exit 1 } removeNalpeironPackages() { nalpeironPackages="zimbra-nalpeiron-offline-daemon nalpdaemon nalppgsql" for i in $nalpeironPackages; do isInstalled $i if [ x$PKGINSTALLED != "x" ]; then echo -n " Removing $i..." $PACKAGERM $i >/dev/null 2>&1 echo "done" fi done if [ -f /etc/sudoers.d/02_zimbra-nalpdaemon ]; then rm /etc/sudoers.d/02_zimbra-nalpdaemon fi } removeExistingPackages() { removeNalpeironPackages echo "" echo "Removing existing packages" echo "" $REPORM zimbra-* >>$LOGFILE 2>&1 if [ $? -ne 0 ]; then echo "Failed to remove existing zimbra packages" exit 1; else echo "done" fi } removeZextrasPackagesIfInstalled() { for i in $ZEXTRAS_PACKAGES; do echo "" echo "Remove $i if it is installed ..." isInstalled $i if [ x$PKGINSTALLED != "x" ]; then echo -n " $i FOUND..." echo "" echo -n " Removing $i..." $PACKAGERM $i >/dev/null 2>&1 echo "done" fi done } removeUnsupportedPackagesIfInstalled() { for i in $DEPRECATED_PACKAGES_IN_10; do echo "" echo "Remove $i if it is installed ..." isInstalled $i if [ x$PKGINSTALLED != "x" ]; then echo -n " $i FOUND..." echo "" echo -n " Removing $i..." $PACKAGERM $i >/dev/null 2>&1 echo "done" fi done } removeExistingInstall() { if [ $INSTALLED = "yes" ]; then echo "" echo "Shutting down zimbra mail" shutDownSystem if [ -f "/opt/zimbra/bin/zmiptables" ]; then /opt/zimbra/bin/zmiptables -u fi isInstalled "zimbra-ldap" if [ x$PKGINSTALLED != "x" ]; then if ( test -x "/opt/zimbra/common/sbin/slapcat" || test -x "/opt/zimbra/openldap/sbin/slapcat" ) && test x"$UNINSTALL" != "xyes" && test x"$REMOVE" != "xyes"; then if [ -d "/opt/zimbra/data/ldap/config" ]; then echo "" echo -n "Backing up the ldap database..." tmpfile=`mktemp -t slapcat.XXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } mkdir -p /opt/zimbra/data/ldap chown -R zimbra:zimbra /opt/zimbra/data/ldap runAsZimbra "/opt/zimbra/libexec/zmslapcat /opt/zimbra/data/ldap" if [ $? != 0 ]; then echo "failed." else echo "done." fi chmod 640 /opt/zimbra/data/ldap/ldap.bak if [ -x /opt/zimbra/libexec/zmslapadd ]; then if [ -f /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{3\}mdb.ldif -o -f /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{3\}hdb.ldif ]; then echo "" echo -n "Backing up the ldap accesslog database..." runAsZimbra "/opt/zimbra/libexec/zmslapcat -a /opt/zimbra/data/ldap" if [ $? != 0 ]; then echo "failed." else echo "done." fi chmod 640 /opt/zimbra/data/ldap/ldap-accesslog.bak fi fi fi fi if [ x"$OLD_LDR_PATH" != "x" ]; then LD_LIBRARY_PATH=$OLD_LDR_PATH fi fi isInstalled "zimbra-zco" if [ x$PKGINSTALLED != "x" ]; then echo -n "Removing stale package zimbra-zco while upgrade..." $PACKAGERM zimbra-zco >/dev/null 2>&1 echo "done" fi if [ "$UPGRADE" = "yes" -a "$POST87UPGRADE" = "true" -a "$FORCE_UPGRADE" != "yes" -a "$ZM_CUR_BUILD" != "$ZM_INST_BUILD" ]; then echo "Upgrading the remote packages" removeZextrasPackagesIfInstalled removeUnsupportedPackagesIfInstalled else removeExistingPackages fi if egrep -q '^%zimbra[[:space:]]' /etc/sudoers 2>/dev/null; then local sudotmp=`mktemp -t zsudoers.XXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } SUDOMODE=`perl -e 'my $mode=(stat("/etc/sudoers"))[2];printf("%04o\n",$mode & 07777);'` egrep -v "^\%zimbra[[:space:]]" /etc/sudoers > $sudotmp mv -f $sudotmp /etc/sudoers chmod $SUDOMODE /etc/sudoers fi echo "" if [ -d "/opt/zimbra/jetty/webapps" ]; then echo "Removing deployed webapp directories" deleteWebApp zimbra jetty deleteWebApp zimbraAdmin jetty deleteWebApp service jetty /bin/rm -rf /opt/zimbra/jetty/work fi fi if [ $REMOVE = "yes" ]; then isInstalled zimbra-base if [ x$PKGINSTALLED != "x" ]; then echo -n " zimbra-base..." $REPORM zimbra-base >>$LOGFILE 2>&1 echo "done" fi if [ ! -L "/opt/zimbra" ]; then echo "" echo "Removing /opt/zimbra" umount /opt/zimbra/amavisd/tmp > /dev/null 2>&1 MOUNTPOINTS=`mount | awk '{print $3}' | grep /opt/zimbra/` for mp in $MOUNTPOINTS; do if [ x$mp != "x/opt/zimbra" ]; then /bin/rm -rf ${mp}/* umount -f ${mp} fi done for i in `ls /opt/zimbra`; do if [ x$i != "xlost+found" ]; then /bin/rm -rf /opt/zimbra/$i fi done if [ -e "/opt/zimbra/.enable_replica" ]; then /bin/rm -f /opt/zimbra/.enable_replica fi if [ -x /usr/bin/crontab ]; then echo -n "Removing zimbra crontab entry..." /usr/bin/crontab -u zimbra -r 2> /dev/null echo "done." fi if [ -L /usr/sbin/sendmail ]; then if [ -x /bin/readlink ]; then SMPATH=$(/bin/readlink /usr/sbin/sendmail) if [ x$SMPATH = x"/opt/zimbra/postfix/sbin/sendmail" -o x$SMPATH = x"/opt/zimbra/common/sbin/sendmail" ]; then /bin/rm -f /usr/sbin/sendmail fi fi fi if [ -L /etc/aliases ]; then if [ -x /bin/readlink ]; then SMPATH=$(/bin/readlink /etc/aliases) if [ x$SMPATH = x"/opt/zimbra/postfix/conf/aliases" -o x$SMPATH = x"/opt/zimbra/common/conf/aliases" ]; then rm -f /etc/aliases fi fi fi if [ -f /etc/syslog-ng/syslog-ng.conf ]; then egrep -q 'zimbra' /etc/syslog-ng/syslog-ng.conf if [ $? = 0 ]; then echo -n "Cleaning up /etc/syslog-ng/syslog-ng.conf..." sed -i -e '/zimbra/d' /etc/syslog-ng/syslog-ng.conf sed -i -e 's/filter f_messages { not facility(news, mail) and not filter(f_iptables) and/filter f_messages { not facility(news, mail) and not filter(f_iptables); };/' /etc/syslog-ng/syslog-ng.conf sed -i -e 's/^ local4, local5, local6, local7) and not/ local4, local5, local6, local7); };/' /etc/syslog-ng/syslog-ng.conf if [ -x /sbin/rcsyslog ]; then /sbin/rcsyslog restart > /dev/null 2>&1 echo "done." else echo "Unable to restart syslog-ng service. Please do it manually." fi fi elif [ -f /etc/rsyslog.conf ]; then if [ -d /etc/rsyslog.d ]; then if [ -f /etc/rsyslog.d/60-zimbra.conf ]; then echo -n "Cleaning up /etc/rsyslog.d..." rm -f /etc/rsyslog.d/60-zimbra.conf if [ -x /usr/bin/systemctl ]; then /usr/sbin/systemctl restart rsyslog.service >/dev/null 2>&1 echo "done." elif [ -x /usr/bin/service ]; then /usr/sbin/service rsyslog restart >/dev/null 2>&1 echo "done." elif [ -x /etc/init.d/rsyslog ]; then /etc/init.d/rsyslog restart > /dev/null 2>&1 echo "done." else echo "Unable to restart rsyslog service. Please do it manually." fi else egrep -q 'zimbra' /etc/rsyslog.conf if [ $? = 0 ]; then echo -n "Cleaning up /etc/rsyslog.conf..." sed -i -e '/zimbra/d' /etc/rsyslog.conf if [ $PLATFORM = "RHEL6_64" -o $PLATFORM = "RHEL7_64" -o $PLATFORM = "RHEL8_64" -o $PLATFORM = "RHEL9_64" ]; then sed -i -e 's/^*.info;local0.none;local1.none;mail.none;auth.none/*.info/' /etc/rsyslog.conf sed -i -e 's/^*.info;local0.none;local1.none;auth.none/*.info/' /etc/rsyslog.conf fi if [ -x /usr/bin/systemctl ]; then /usr/sbin/systemctl restart rsyslog.service >/dev/null 2>&1 echo "done." elif [ -x /usr/bin/service ]; then /usr/sbin/service rsyslog restart >/dev/null 2>&1 echo "done." elif [ -x /etc/init.d/rsyslog ]; then /etc/init.d/rsyslog restart > /dev/null 2>&1 echo "done." else echo "Unable to restart rsyslog service. Please do it manually." fi fi fi fi fi echo -n "Cleaning up zimbra init scripts..." if [ -x /sbin/chkconfig ]; then /sbin/chkconfig zimbra off 2> /dev/null /sbin/chkconfig --del zimbra 2> /dev/null else /bin/rm -f /etc/rc*.d/S99zimbra 2> /dev/null /bin/rm -f /etc/rc*.d/K01zimbra 2> /dev/null fi if [ -f /etc/init.d/zimbra ]; then /bin/rm -f /etc/init.d/zimbra fi echo "done." if [ -f /etc/logrotate.d/zimbra ]; then echo -n "Cleaning up /etc/logrotate.d/zimbra..." /bin/rm -f /etc/logrotate.d/zimbra 2> /dev/null echo "done." fi if [ -f /etc/security/limits.conf ]; then echo -n "Cleaning up /etc/security/limits.conf..." egrep -q '^zimbra|^liquid' /etc/security/limits.conf if [ $? = 0 ]; then sed -i -e '/^zimbra/d' -e '/^liquid/d' /etc/security/limits.conf fi echo "done." fi if [ -f /etc/security/limits.d/80-zimbra.conf ]; then echo -n "Cleaning up /etc/security/limits.d/80-zimbra.conf..." rm -f /etc/security/limits.d/80-zimbra.conf echo "done." fi if [ -f /etc/security/limits.d/10-zimbra.conf ]; then echo -n "Cleaning up /etc/security/limits.d/10-zimbra.conf..." rm -f /etc/security/limits.d/10-zimbra.conf echo "done." fi for mp in $MOUNTPOINTS; do if [ x$mp != "x/opt/zimbra" ]; then mkdir -p ${mp} mount ${mp} fi done echo "" echo "Finished removing Zimbra Collaboration Server." echo "" fi fi } setServiceIP() { askNonBlank "Please enter the service IP for this host" "$SERVICEIP" SERVICEIP=$response } setHostName() { OLD=$HOSTNAME while :; do askNonBlank "Please enter the logical hostname for this host" "$HOSTNAME" fq=`isFQDN $response` if [ $fq = 1 ]; then HOSTNAME=$response break else echo "" echo "Please enter a fully qualified hostname" fi done if [ "x$OLD" != "x$HOSTNAME" ]; then if [ "x$SMTPHOST" = "x$OLD" ]; then SMTPHOST=$HOSTNAME fi if [ "x$SNMPTRAPHOST" = "x$OLD" ]; then SNMPTRAPHOST=$HOSTNAME fi if [ "x$CREATEDOMAIN" = "x$OLD" ]; then CREATEDOMAIN=$HOSTNAME fi fi } checkConflicts() { echo "" echo "Checking for sendmail/postfix" echo "" if [ -f /var/lock/subsys/postfix ]; then askYN "Postfix appears to be running. Shut it down?" "Y" if [ $response = "yes" ]; then /etc/init.d/postfix stop if [ -x /sbin/chkconfig ]; then /sbin/chkconfig postfix off fi fi fi if [ -f /var/lock/subsys/sendmail ]; then askYN "Sendmail appears to be running. Shut it down?" "Y" if [ $response = "yes" ]; then /etc/init.d/sendmail stop if [ -x /sbin/chkconfig ]; then /sbin/chkconfig sendmail off fi fi fi echo "" echo "Checking for exim4" echo "" if [ -f /var/run/exim4/exim.pid ]; then askYN "Exim4 appears to be running. Shut it down?" "Y" if [ $response = "yes" ]; then /etc/init.d/exim4 stop /usr/sbin/update-rc.d -f exim4 remove fi fi echo "" echo "Checking for mysqld" echo "" if [ -f /var/lock/subsys/mysqld ]; then while :; do askYN "Mysql appears to be running. Shut it down?" "Y" if [ $response = "yes" ]; then /etc/init.d/mysqld stop if [ -x /sbin/chkconfig ]; then /sbin/chkconfig mysqld off fi break else echo "Installation will probably fail with mysql running" askYN "Install anyway?" "N" if [ $response = "yes" ]; then break else askYN "Exit?" "N" if [ $response = "yes" ]; then echo "Exiting - the system is unchanged" exit 1 fi fi fi done fi } cleanUp() { # Dump all the config data to a file runAsZimbra "zmlocalconfig -s > .localconfig.save.$$" runAsZimbra "zmprov gs $HOSTNAME > .zmprov.$HOSTNAME.save.$$" runAsZimbra "zmprov gacf $HOSTNAME > .zmprov.gacf.save.$$" } verifyLdapServer() { if [ $LDAP_HERE = "yes" ]; then LDAPOK="yes" return fi echo "" echo -n "Contacting ldap server $LDAPHOST on $LDAPPORT..." $MYLDAPSEARCH -x -h $LDAPHOST -p $LDAPPORT -w $LDAPZIMBRAPW -D "uid=zimbra,cn=admins,cn=zimbra" > /dev/null 2>&1 LDAPRESULT=$? if [ $LDAPRESULT != 0 ]; then echo "FAILED" LDAPOK="no" else echo "Success" LDAPOK="yes" fi } configurePackageServer() { echo -e "" response="no" TMP_PACKAGE_SERVER="repo.zimbra.com" if [ x"$USE_ZIMBRA_PACKAGE_SERVER" = "x" ]; then askYN "Use Zimbra's package repository" "Y" if [ $response = "yes" ]; then USE_ZIMBRA_PACKAGE_SERVER="yes" PACKAGE_SERVER="repo.zimbra.com" response="no" echo $HOSTNAME | egrep -qe 'eng.zimbra.com$|lab.zimbra.com$|zimbradev.com$' > /dev/null 2>&1 if [ $? = 0 ]; then askYN "Use internal development repo" "N" if [ $response = "yes" ]; then PACKAGE_SERVER="repo-dev.eng.zimbra.com" else response="no" askYN "Use internal production mirror" "N" if [ $response = "yes" ]; then PACKAGE_SERVER="repo.eng.zimbra.com" fi fi fi fi fi if [ x"$USE_ZIMBRA_PACKAGE_SERVER" = "xyes" ]; then # Handle automated installations correctly echo ""; if [ x"$PACKAGE_SERVER" = "x" ]; then # Allow config files w/ no PACKAGE_SERVER variable set PACKAGE_SERVER=$TMP_PACKAGE_SERVER fi echo $PLATFORM | egrep -q "UBUNTU|DEBIAN" if [ $? = 0 ]; then if [ $PLATFORM = "UBUNTU24_64" ]; then repo="noble" elif [ $PLATFORM = "UBUNTU22_64" ]; then repo="jammy" elif [ $PLATFORM = "UBUNTU20_64" ]; then repo="focal" elif [ $PLATFORM = "UBUNTU18_64" ]; then repo="bionic" elif [ $PLATFORM = "UBUNTU16_64" ]; then repo="xenial" elif [ $PLATFORM = "UBUNTU14_64" ]; then repo="trusty" elif [ $PLATFORM = "UBUNTU12_64" ]; then repo="precise" else print "Aborting, unknown platform: $PLATFORM" exit 1 fi gpg --list-keys --keyring /etc/apt/trusted.gpg.d/zimbra.gpg 2>/dev/null | grep -w 254F9170B966D193D6BAD300D5CEF8BF9BE6ED79 >/dev/null if [ $? -ne 0 ]; then echo "Importing Zimbra GPG key" gpg --no-default-keyring --keyring /tmp/zimbra.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 9BE6ED79 >>$LOGFILE 2>&1 if [ $? -ne 0 ]; then echo "ERROR: Unable to retrive Zimbra GPG key for package validation" echo "Please fix system to allow normal package installation before proceeding" exit 1 else gpg --no-default-keyring --keyring /tmp/zimbra.gpg --export > /etc/apt/trusted.gpg.d/zimbra.gpg if [ $? -ne 0 ]; then echo "ERROR: Unable to export Zimbra GPG key for package validation" exit 1 else rm -f /tmp/zimbra.gpg fi fi fi echo echo "Configuring package repository" apt-get install -y apt-transport-https >>$LOGFILE 2>&1 if [ $? -ne 0 ]; then echo "ERROR: Unable to install packages via apt-get" echo "Please fix system to allow normal package installation before proceeding" exit 1 fi if [ "$PLATFORM" = "UBUNTU24_64" ]; then cat > /etc/apt/sources.list.d/zimbra.sources << EOF Types: deb deb-src URIs: https://$PACKAGE_SERVER/apt/87 Suites: $repo Components: zimbra Architectures: amd64 Signed-By: /etc/apt/trusted.gpg.d/zimbra.gpg Types: deb URIs: https://$PACKAGE_SERVER/apt/1000 Suites: $repo Components: zimbra Architectures: amd64 Signed-By: /etc/apt/trusted.gpg.d/zimbra.gpg Types: deb URIs: https://$PACKAGE_SERVER/apt/1010 Suites: $repo Components: zimbra Architectures: amd64 Signed-By: /etc/apt/trusted.gpg.d/zimbra.gpg EOF if [ "x$ZMTYPE_INSTALLABLE" = "xNETWORK" ]; then cat >> /etc/apt/sources.list.d/zimbra.sources << EOF Types: deb URIs: https://$PACKAGE_SERVER/apt/1000-ne Suites: $repo Components: zimbra Architectures: amd64 Signed-By: /etc/apt/trusted.gpg.d/zimbra.gpg Types: deb URIs: https://$PACKAGE_SERVER/apt/1010-ne Suites: $repo Components: zimbra Architectures: amd64 Signed-By: /etc/apt/trusted.gpg.d/zimbra.gpg EOF cat > /etc/apt/sources.list.d/zimbra-onlyoffice.sources << EOF Types: deb URIs: https://$PACKAGE_SERVER/apt/onlyoffice-1010 Suites: $repo Components: zimbra Architectures: amd64 Signed-By: /etc/apt/trusted.gpg.d/zimbra.gpg EOF fi else cat > /etc/apt/sources.list.d/zimbra.list << EOF deb [arch=amd64] https://$PACKAGE_SERVER/apt/87 $repo zimbra deb-src [arch=amd64] https://$PACKAGE_SERVER/apt/87 $repo zimbra deb [arch=amd64] https://$PACKAGE_SERVER/apt/1000 $repo zimbra deb [arch=amd64] https://$PACKAGE_SERVER/apt/1010 $repo zimbra EOF if [ "x$ZMTYPE_INSTALLABLE" = "xNETWORK" ]; then cat >> /etc/apt/sources.list.d/zimbra.list << EOF deb [arch=amd64] https://$PACKAGE_SERVER/apt/1000-ne $repo zimbra deb [arch=amd64] https://$PACKAGE_SERVER/apt/1010-ne $repo zimbra EOF cat > /etc/apt/sources.list.d/zimbra-onlyoffice.list << EOF deb [arch=amd64] https://$PACKAGE_SERVER/apt/onlyoffice-1010 $repo zimbra EOF fi fi apt-get update >>$LOGFILE 2>&1 if [ $? -ne 0 ]; then echo "ERROR: Unable to install packages via apt-get" echo "Please fix system to allow normal package installation before proceeding" exit 1 fi else if [ $PLATFORM = "RHEL6_64" ]; then repo="rhel6" elif [ $PLATFORM = "RHEL7_64" ]; then repo="rhel7" elif [ $PLATFORM = "RHEL8_64" ]; then repo="rhel8" elif [ $PLATFORM = "RHEL9_64" ]; then repo="rhel9" else print "Aborting, unknown platform: $PLATFORM" exit 1 fi if [ $PLATFORM = "RHEL9_64" ]; then rpm -q gpg-pubkey-7c66bd84-6583eafa > /dev/null else rpm -q gpg-pubkey-0f30c305-5564be70 > /dev/null fi if [ $? -ne 0 ]; then echo "Importing Zimbra GPG key" if [ $PLATFORM = "RHEL9_64" ]; then rpm --import https://files.zimbra.com/downloads/security/public-sha-256.key >>$LOGFILE 2>&1 else rpm --import https://files.zimbra.com/downloads/security/public.key >>$LOGFILE 2>&1 fi if [ $? -ne 0 ]; then echo "ERROR: Unable to retrive Zimbra GPG key for package validation" echo "Please fix system to allow normal package installation before proceeding" exit 1 fi fi echo echo "Configuring package repository" cat > /etc/yum.repos.d/zimbra.repo <>$LOGFILE 2>&1 yum check-update --disablerepo=* --enablerepo=zimbra --noplugins >>$LOGFILE 2>&1 yum --disablerepo=* --enablerepo=zimbra-1000-oss clean metadata >>$LOGFILE 2>&1 yum check-update --disablerepo=* --enablerepo=zimbra-1000-oss --noplugins >>$LOGFILE 2>&1 yum --disablerepo=* --enablerepo=zimbra-1010-oss clean metadata >>$LOGFILE 2>&1 yum check-update --disablerepo=* --enablerepo=zimbra-1010-oss --noplugins >>$LOGFILE 2>&1 if [ x"$ZMTYPE_INSTALLABLE" = "xNETWORK" ]; then cat >> /etc/yum.repos.d/zimbra.repo <> /etc/yum.repos.d/zimbra.repo < /etc/yum.repos.d/zimbra-onlyoffice.repo <>$LOGFILE 2>&1 yum check-update --disablerepo=* --enablerepo=zimbra-1000-network --noplugins >>$LOGFILE 2>&1 yum --disablerepo=* --enablerepo=zimbra-1010-network clean metadata >>$LOGFILE 2>&1 yum check-update --disablerepo=* --enablerepo=zimbra-1010-network --noplugins >>$LOGFILE 2>&1 yum --disablerepo=* --enablerepo=zimbra-onlyoffice clean metadata >>$LOGFILE 2>&1 yum check-update --disablerepo=* --enablerepo=zimbra-onlyoffice --noplugins >>$LOGFILE 2>&1 fi if [ $? -ne 0 -a $? -ne 100 ]; then echo "ERROR: yum check-update failed" echo "Please validate ability to install packages" exit 1 fi fi fi } getInstallPackages() { echo "" if [ $UPGRADE = "yes" ]; then echo "Scanning for any new or additional packages available for installation" echo "Existing packages will be upgraded" echo " Upgrading zimbra-core" else echo "Select the packages to install" fi APACHE_SELECTED="no" LOGGER_SELECTED="no" STORE_SELECTED="no" MTA_SELECTED="no" PROXY_SELECTED="no" LDAP_SELECTED="no" ONLYOFFICE_SELECTED="no" LICENSE_DAEMON_SELECTED="no" for i in $AVAILABLE_PACKAGES; do if [ $i = "zimbra-core" ]; then continue fi # Reset the response before processing the next package. response="no" # If we're upgrading, and it's installed, don't ask stoopid questions if [ $UPGRADE = "yes" ]; then echo $INSTALLED_PACKAGES | grep $i > /dev/null 2>&1 if [ $? = 0 ]; then echo " Upgrading $i" if [ $i = "zimbra-mta" ]; then CONFLICTS="no" for j in $CONFLICT_PACKAGES; do conflictInstalled $j if [ "x$CONFLICTINSTALLED" != "x" ]; then echo " Conflicting package: $CONFLICTINSTALLED" CONFLICTS="yes" fi done if [ $CONFLICTS = "yes" ]; then echo "" echo "###ERROR###" echo "" echo "One or more package conflicts exists." echo "Please remove them before running this installer." echo "" echo "Installation cancelled." echo "" exit 1 fi fi INSTALL_PACKAGES="$INSTALL_PACKAGES $i" if [ $i = "zimbra-apache" ]; then APACHE_SELECTED="yes" elif [ $i = "zimbra-logger" ]; then LOGGER_SELECTED="yes" elif [ $i = "zimbra-license-daemon" ]; then LICENSE_DAEMON_SELECTED="yes" elif [ $i = "zimbra-store" ]; then STORE_SELECTED="yes" checkLicenseDaemonServiceRunning $LICENSE_DAEMON_SELECTED elif [ $i = "zimbra-mta" ]; then MTA_SELECTED="yes" elif [ $i = "zimbra-proxy" ]; then PROXY_SELECTED="yes" elif [ $i = "zimbra-ldap" ]; then LDAP_SELECTED="yes" elif [ $i = "zimbra-onlyoffice" ]; then ONLYOFFICE_SELECTED="yes" fi continue fi fi # askInstallPkgYN args : PROMPT REQUIRE_STORE=yes|no YES_STORE_DEFAULT=Y|N NO_STORE_DEFAULT=Y|N ZIMBRAINTERNAL=no echo $HOSTNAME | egrep -qe 'eng.zimbra.com$|lab.zimbra.com$|zimbradev.com$' > /dev/null 2>&1 if [ $? = 0 ]; then ZIMBRAINTERNAL=yes fi if [ $i = "zimbra-license-tools" ]; then response="yes" elif [ $i = "zimbra-modern-ui" ]; then ifStoreSelectedY elif [ $i = "zimbra-modern-zimlets" ]; then ifStoreSelectedY elif [ $i = "zimbra-zimlet-document-editor" ]; then ifStoreSelectedY elif [ $i = "zimbra-zimlet-classic-document-editor" ]; then ifStoreSelectedY elif [ $i = "zimbra-zimlet-classic-set-default-client" ]; then ifStoreSelectedY elif [ $i = "zimbra-patch" ]; then if [ x"$ZIMBRAINTERNAL" = "xyes" ] && [ $STORE_SELECTED = "yes" ]; then askYN "Install $i" "Y" else ifStoreSelectedY fi elif [ $i = "zimbra-mta-patch" ]; then if [ x"$ZIMBRAINTERNAL" = "xyes" ] && [ $MTA_SELECTED = "yes" ]; then askYN "Install $i" "Y" else response="$MTA_SELECTED" fi elif [ $i = "zimbra-proxy-patch" ]; then if [ x"$ZIMBRAINTERNAL" = "xyes" ] && [ $PROXY_SELECTED = "yes" ]; then askYN "Install $i" "Y" else response="$PROXY_SELECTED" fi elif [ $i = "zimbra-ldap-patch" ]; then if [ x"$ZIMBRAINTERNAL" = "xyes" ] && [ $LDAP_SELECTED = "yes" ]; then askYN "Install $i" "Y" else response="$LDAP_SELECTED" fi elif [ $i = "zimbra-onlyoffice-patch" ]; then if [ x"$ZIMBRAINTERNAL" = "xyes" ] && [ $ONLYOFFICE_SELECTED = "yes" ]; then askYN "Install $i" "Y" else response="$ONLYOFFICE_SELECTED" fi elif [ $i = "zimbra-lds-patch" ]; then if [ x"$ZIMBRAINTERNAL" = "xyes" ] && [ $LICENSE_DAEMON_SELECTED = "yes" ]; then askYN "Install $i" "Y" else response="$LICENSE_DAEMON_SELECTED" fi elif [ $i = "zimbra-license-extension" ]; then ifStoreSelectedY elif [ $i = "zimbra-network-store" ]; then ifStoreSelectedY elif [ $UPGRADE = "yes" ]; then if [ $i = "zimbra-archiving" ]; then askInstallPkgYN "Install $i" "yes" "N" "N" elif [ $i = "zimbra-imapd" ]; then askInstallPkgYN "Install $i (BETA - for evaluation only)" "no" "N" "N" else askYN "Install $i" "N" fi else if [ $i = "zimbra-archiving" ]; then askInstallPkgYN "Install $i" "yes" "N" "N" elif [ $i = "zimbra-convertd" ]; then askInstallPkgYN "Install $i" "no" "Y" "N" elif [ $i = "zimbra-imapd" ]; then askInstallPkgYN "Install $i (BETA - for evaluation only)" "no" "N" "N" elif [ $i = "zimbra-dnscache" ]; then if [ $MTA_SELECTED = "yes" ]; then askYN "Install $i" "Y" else askYN "Install $i" "N" fi else askYN "Install $i" "Y" fi fi if [ $response = "yes" ]; then if [ $i = "zimbra-logger" ]; then LOGGER_SELECTED="yes" elif [ $i = "zimbra-license-daemon" ]; then LICENSE_DAEMON_SELECTED="yes" elif [ $i = "zimbra-store" ]; then STORE_SELECTED="yes" checkLicenseDaemonServiceRunning $LICENSE_DAEMON_SELECTED elif [ $i = "zimbra-apache" ]; then APACHE_SELECTED="yes" elif [ $i = "zimbra-mta" ]; then MTA_SELECTED="yes" elif [ $i = "zimbra-proxy" ]; then PROXY_SELECTED="yes" elif [ $i = "zimbra-ldap" ]; then LDAP_SELECTED="yes" elif [ $i = "zimbra-onlyoffice" ]; then ONLYOFFICE_SELECTED="yes" fi if [ $i = "zimbra-mta" ]; then CONFLICTS="no" for j in $CONFLICT_PACKAGES; do conflictInstalled $j if [ "x$CONFLICTINSTALLED" != "x" ]; then echo " Conflicting package: $CONFLICTINSTALLED" CONFLICTS="yes" fi done if [ $CONFLICTS = "yes" ]; then echo "" echo "###ERROR###" echo "" echo "One or more package conflicts exists." echo "Please remove them before running this installer." echo "" echo "Installation cancelled." echo "" exit 1 fi fi if [ $i = "zimbra-spell" -a $APACHE_SELECTED = "no" ]; then APACHE_SELECTED="yes" INSTALL_PACKAGES="$INSTALL_PACKAGES zimbra-apache" fi if [ $i = "zimbra-convertd" -a $APACHE_SELECTED = "no" ]; then APACHE_SELECTED="yes" INSTALL_PACKAGES="$INSTALL_PACKAGES zimbra-apache" fi INSTALL_PACKAGES="$INSTALL_PACKAGES $i" fi done isp7zipRequired checkRequiredSpace isInstalled zimbra-store isToBeInstalled zimbra-store if [ "x$PKGINSTALLED" != "x" -o "x$PKGTOBEINSTALLED" != "x" ]; then checkStoreRequirements fi isOnlyofficeStandalone $ONLYOFFICE_SELECTED echo "" echo "Installing:" for i in $INSTALL_PACKAGES; do echo " $i" done } isp7zipRequired() { P7ZIPREQUIRED=no if [[ $MTA_SELECTED == "yes" && $PLATFORM = "RHEL9_64" ]]; then isInstalled p7zip-plugins if [ x$PKGINSTALLED = "x" ]; then askYN "Install p7zip-plugins from epel-release repository (without p7zip-plugins, some decoders for Amavis may not be available)." "Y" if [ $response = "yes" ]; then P7ZIPREQUIRED=yes fi fi fi } installEPELRepo() { if [ $P7ZIPREQUIRED = "yes" ]; then OS_NAME=`grep -E '^(NAME)=' /etc/os-release | cut -d = -f 2 | tr -d '"'` case "$OS_NAME" in "Red Hat"*) isInstalled epel-release-latest-9 if [ x$PKGINSTALLED = "x" ]; then echo -n "Installing epel-release-latest-9..." if ! yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -y >>$LOGFILE 2>&1 ; then echo "failed to install epel-release." exit 1 else echo "done." fi fi echo -n "Installing p7zip-plugins..." if ! yum install p7zip-plugins --enablerepo=epel -y >>$LOGFILE 2>&1 ; then echo "failed to install p7zip-plugins." exit 1 else echo "done." fi ;; "Oracle"*) isInstalled oracle-epel-release-el9 if [ x$PKGINSTALLED = "x" ]; then echo -n "Installing oracle-epel-release-el9..." if ! yum install oracle-epel-release-el9 -y >>$LOGFILE 2>&1 ; then echo "failed to install epel-release." exit 1 else echo "done." fi fi echo -n "Installing p7zip-plugins..." if ! yum install p7zip-plugins --enablerepo=ol9_developer_EPEL -y >>$LOGFILE 2>&1 ; then echo "failed to install p7zip-plugins." exit 1 else echo "done." fi ;; "Rocky"*|"CentOS"*) isInstalled epel-release if [ x$PKGINSTALLED = "x" ]; then echo -n "Installing epel-release..." if ! yum install epel-release -y > /dev/null >>$LOGFILE 2>&1 ; then echo "failed to install epel-release." exit 1 else echo "done." fi fi echo -n "Installing p7zip-plugins..." if ! yum install p7zip-plugins --enablerepo=epel -y >>$LOGFILE 2>&1; then echo "failed to install p7zip-plugins." exit 1 else echo "done." fi ;; esac fi } checkLicenseDaemonServiceRunning() { if [ x"$ZMTYPE_INSTALLABLE" = "xNETWORK" ]; then LICENSE_DAEMON_PKG=$1 LICENSE_DAEMON_HOST="" LICENSE_DAEMON_PORT="8081" if [ $LICENSE_DAEMON_PKG == "no" ]; then if [ $UPGRADE = "yes" ]; then LDAP_URL_LIST=$(su - zimbra -c "zmlocalconfig -m nokey -s ldap_url") LDAP_STARTTLS_SUPPORTED=$(su - zimbra -c "zmlocalconfig -m nokey -s ldap_starttls_supported") LDAP_BIND_DN=$(su - zimbra -c "zmlocalconfig -m nokey -s zimbra_ldap_userdn") LDAP_BIND_PASSWORD=$(su - zimbra -c "zmlocalconfig -m nokey -s zimbra_ldap_password") LICENSE_DAEMON_FOUND=0 for ldap_url in $LDAP_URL_LIST; do if [[ "$ldap_url" =~ ^ldap:// ]] && [[ "$LDAP_STARTTLS_SUPPORTED" == "true" || "$LDAP_STARTTLS_SUPPORTED" == "1" ]]; then echo "Trying ldapsearch on $ldap_url with -ZZ" >> $LOGFILE LDAP_RESULT=$(su - zimbra -c "ldapsearch -x -H \"$ldap_url\" -ZZ -D \"$LDAP_BIND_DN\" -w \"$LDAP_BIND_PASSWORD\" -b \"cn=config,cn=zimbra\" \"(objectClass=zimbraGlobalConfig)\" zimbraLicenseDaemonServerHost" 2>>"$LOGFILE") LDAP_EXIT_CODE=$? else echo "Trying ldapsearch on $ldap_url without -ZZ" >> $LOGFILE LDAP_RESULT=$(su - zimbra -c "ldapsearch -x -H \"$ldap_url\" -D \"$LDAP_BIND_DN\" -w \"$LDAP_BIND_PASSWORD\" -b \"cn=config,cn=zimbra\" \"(objectClass=zimbraGlobalConfig)\" zimbraLicenseDaemonServerHost" 2>>"$LOGFILE") LDAP_EXIT_CODE=$? fi if [ $LDAP_EXIT_CODE -ne 0 ]; then echo "ldapsearch failed on $ldap_url with exit code $LDAP_EXIT_CODE" >> $LOGFILE continue fi LICENSE_DAEMON_HOST=$(echo "$LDAP_RESULT" | awk '/^zimbraLicenseDaemonServerHost: /{print $2}') if [ -n "$LICENSE_DAEMON_HOST" ]; then echo "Found zimbraLicenseDaemonServerHost: $LICENSE_DAEMON_HOST via $ldap_url" >> $LOGFILE LICENSE_DAEMON_FOUND=1 break fi done if [ $LICENSE_DAEMON_FOUND -eq 0 ]; then printWarning "zimbra-license-daemon should be installed prior to zimbra-store" exit 1 fi fi if [ -z "$LICENSE_DAEMON_HOST" ]; then askYN "Have you installed zimbra-license-daemon package on different node" "N" if [ $response = "yes" ]; then askNonBlank "Please enter the zimbra-license-daemon host" "$LICENSE_DAEMON_HOST" LICENSE_DAEMON_HOST=$response else printWarning "zimbra-license-daemon should be installed prior to zimbra-store" exit 1 fi fi LICENSE_DAEMON_API="http://${LICENSE_DAEMON_HOST}:${LICENSE_DAEMON_PORT}/actuator/health" LICENSE_DAEMON_STATUS=$(curl -s --connect-timeout 5 "$LICENSE_DAEMON_API") if [ $? -ne 0 ]; then printWarning "Failed to connect to $LICENSE_DAEMON_API" printWarning "license-daemon should be running and healthy." exit 1 else if [[ "$LICENSE_DAEMON_STATUS" != *'"status":"UP"'* ]]; then printWarning "license-daemon is not running. license-daemon should be running and healthy." exit 1 fi fi fi fi } printWarning() { echo -e "\033[0;31m$@\033[0m" } isOnlyofficeStandalone() { onlyofficepkg=$1 # check if store is being installed too. # if it is not being intsalled, add zimbra-mariadb to the list of packages to be installed isInstalled zimbra-store isToBeInstalled zimbra-store isStandAlone="yes" if [ "x$PKGINSTALLED" != "x" -o "x$PKGTOBEINSTALLED" != "x" ]; then isStandAlone="no" fi ## install rabbit mq if [ $onlyofficepkg == "yes" ]; then INSTALL_PACKAGES="$INSTALL_PACKAGES zimbra-rabbitmq-server" fi if [ $isStandAlone == "yes" -a $onlyofficepkg == "yes" ]; then INSTALL_PACKAGES="$INSTALL_PACKAGES zimbra-mariadb" fi } removeZimbraPatch(){ isInstalled zimbra-patch if [ x$PKGINSTALLED != "x" ]; then echo -n "Removing zimbra-patch..." $PACKAGERM zimbra-patch >/dev/null 2>&1 echo "done" fi } removeModernUI(){ isInstalled zimbra-modern-ui if [ x$PKGINSTALLED != "x" ]; then echo -n "Removing zimbra-modern-ui..." $PACKAGERM zimbra-modern-ui >/dev/null 2>&1 echo "done" fi } deleteWebApp() { WEBAPPNAME=$1 CONTAINERDIR=$2 /bin/rm -rf /opt/zimbra/$CONTAINERDIR/webapps/$WEBAPPNAME /bin/rm -rf /opt/zimbra/$CONTAINERDIR/webapps/$WEBAPPNAME.war if [ $WEBAPPNAME == "zimbra" ]; then #zimbra-modern-ui package needs to re-install #because deleting /opt/zimbra/jetty/webapps/zimbra/ will remove modern directory from webapps #so first uninstall zimbra-modern-ui to install it # To remove zimbra-modern-ui,first zimbra-patch needs to remove removeZimbraPatch removeModernUI fi } setInstallPackages() { for i in $OPTIONAL_PACKAGES; do isInstalled $i if [ x$PKGINSTALLED != "x" ]; then INSTALL_PACKAGES="$INSTALL_PACKAGES $i" fi done for i in $PACKAGES $CORE_PACKAGES; do isInstalled $i if [ x$PKGINSTALLED != "x" ]; then INSTALL_PACKAGES="$INSTALL_PACKAGES $i" fi done } setHereFlags() { setInstallPackages LDAP_HERE="no" POSTFIX_HERE="no" STORE_HERE="no" SNMP_HERE="no" LOGGER_HERE="no" for i in $INSTALL_PACKAGES; do if [ $i = "zimbra-store" ]; then STORE_HERE="yes" fi if [ $i = "zimbra-mta" ]; then POSTFIX_HERE="yes" # Don't change it if we read in a value from an existing config. if [ "x$RUNAV" = "x" ]; then RUNAV="yes" fi if [ "x$RUNSA" = "x" ]; then RUNSA="yes" fi fi if [ $i = "zimbra-ldap" ]; then LDAP_HERE="yes" fi if [ $i = "zimbra-snmp" ]; then SNMP_HERE="yes" fi if [ $i = "zimbra-logger" ]; then LOGGER_HERE="yes" fi done } startServers() { echo -n "Starting servers..." runAsZimbra "zmcontrol startup" su - zimbra -c "zmcontrol status" echo "done" } verifyExecute() { while :; do askYN "The system will be modified. Continue?" "N" if [ $response = "no" ]; then askYN "Exit?" "N" if [ $response = "yes" ]; then echo "Exiting - the system is unchanged" exit 1 fi else break fi done } setupCrontab() { crontab -u zimbra -l > /tmp/crontab.zimbra.orig grep ZIMBRASTART /tmp/crontab.zimbra.orig > /dev/null 2>&1 if [ $? != 0 ]; then cat /dev/null > /tmp/crontab.zimbra.orig fi grep ZIMBRAEND /tmp/crontab.zimbra.orig > /dev/null 2>&1 if [ $? != 0 ]; then cat /dev/null > /tmp/crontab.zimbra.orig fi cat /tmp/crontab.zimbra.orig | sed -e '/# ZIMBRASTART/,/# ZIMBRAEND/d' > \ /tmp/crontab.zimbra.proc cp -f /opt/zimbra/conf/crontabs/crontab /tmp/crontab.zimbra isInstalled zimbra-store if [ x$PKGINSTALLED != "x" ]; then cat /opt/zimbra/conf/crontabs/crontab.store >> /tmp/crontab.zimbra fi isInstalled zimbra-logger if [ x$PKGINSTALLED != "x" ]; then cat /opt/zimbra/conf/crontabs/crontab.logger >> /tmp/crontab.zimbra fi echo "# ZIMBRAEND -- DO NOT EDIT ANYTHING BETWEEN THIS LINE AND ZIMBRASTART" >> /tmp/crontab.zimbra cat /tmp/crontab.zimbra.proc >> /tmp/crontab.zimbra crontab -u zimbra /tmp/crontab.zimbra } isToBeInstalled() { pkg=$1 PKGTOBEINSTALLED="" for i in $INSTALL_PACKAGES; do if [ "x$pkg" = "x$i" ]; then PKGTOBEINSTALLED=$i continue fi done } isInstalled() { pkg=$1 PKGINSTALLED="" if [ "x$PACKAGEEXT" = "xrpm" ]; then $PACKAGEQUERY $pkg >/dev/null 2>&1 if [ $? = 0 ]; then PKGVERSION=`$PACKAGEQUERY $pkg 2> /dev/null | sort -u` PKGINSTALLED=`$PACKAGEQUERY $pkg | sed -e 's/\.[a-zA-Z].*$//' 2> /dev/null` fi elif [ "x$PACKAGEEXT" = "xccs" ]; then $PACKAGEQUERY $pkg >/dev/null 2>&1 if [ $? = 0 ]; then PKGVERSION=`$PACKAGEQUERY $pkg 2> /dev/null | sort -u` PKGINSTALLED=`$PACKAGEQUERY $pkg | sed -e 's/\.[a-zA-Z].*$//' 2> /dev/null` fi else Q=`$PACKAGEQUERY $pkg 2>/dev/null | egrep '^Status: ' ` if [ "x$Q" != "x" ]; then echo $Q | grep 'not-installed' > /dev/null 2>&1 if [ $? != 0 ]; then echo $Q | grep 'deinstall ok' > /dev/null 2>&1 if [ $? != 0 ]; then PKGVERSION=`$PACKAGEQUERY $pkg | egrep '^Version: ' | sed -e 's/Version: //' 2> /dev/null` PKGINSTALLED="${pkg}-${PKGVERSION}" fi fi fi fi } conflictInstalled() { pkg=$1 CONFLICTINSTALLED="" QP=`dpkg-query -W -f='\${Package}: \${Provides}\n' '*' | grep ": .*$pkg" | sed -e 's/:.*//'` while [ "x$QP" != "x" ]; do QF=`echo $QP | sed -e 's/\s.*//'` QP=`echo $QP | sed -e 's/\S*\s*//'` isInstalled $QF if [ x$PKGINSTALLED != "x" ]; then CONFLICTINSTALLED=$QF if [ x$CONFLICTINSTALLED = "xzimbra-mta" ]; then CONFLICTINSTALLED="" fi fi done } suggestedVersion() { pkg=$1 PKGINSTALLED="" if [ "x$PACKAGEEXT" = "xrpm" ]; then $PACKAGEQUERY $pkg >/dev/null 2>&1 if [ $? = 0 ]; then PKGINSTALLED=`$PACKAGEQUERY $pkg | sed -e 's/\.[a-zA-Z].*$//' 2> /dev/null` else sugpkg=${pkg%-*} PKGVERSION=`$PACKAGEQUERY $sugpkg 2> /dev/null | sort -u | grep -v 'not installed$'` PKGVERSION=${PKGVERSION:-notfound} fi elif [ $PACKAGEEXT = "ccs" ]; then $PACKAGEQUERY $pkg >/dev/null 2>&1 if [ $? = 0 ]; then PKGINSTALLED=`$PACKAGEQUERY $pkg | sed -e 's/\.[a-zA-Z].*$//' 2> /dev/null` else sugpkg=${pkg%=*} PKGVERSION=`$PACKAGEQUERY $sugpkg 2> /dev/null | sort -u` fi else sugpkg=${pkg%-*} sugversion=${pkg#*-} Q=`$PACKAGEQUERY $sugpkg 2>/dev/null | egrep '^Status: ' ` if [ "x$Q" != "x" ]; then echo $Q | grep 'not-installed' > /dev/null 2>&1 if [ $? != 0 ]; then PKGVERSION=`$PACKAGEVERSION $sugpkg 2> /dev/null` if [ x"$sugversion" != x"$sugpkg" ]; then if [[ "$PKGVERSION" == "$sugversion"* ]]; then PKGINSTALLED="${sugpkg}-${PKGVERSION}" fi else PKGINSTALLED="${sugpkg}-${PKGVERSION}" fi fi fi fi } getPlatformVars() { CONFLICT_PACKAGES="" echo $PLATFORM | egrep -q "UBUNTU|DEBIAN" if [ $? = 0 ]; then ISUBUNTU=true checkUbuntuRelease REPOINST='apt-get install -y' PACKAGEDOWNLOAD='apt-get --download-only install -y --force-yes' REPORM='apt-get -y --purge purge' PACKAGEINST='dpkg -i --auto-deconfigure' PACKAGERM='dpkg --purge' PACKAGERMSIMULATE='dpkg --purge --dry-run' PACKAGEQUERY='dpkg -s' PACKAGEEXT='deb' PACKAGEVERSION="dpkg-query -W -f \${Version}" CONFLICT_PACKAGES="mail-transport-agent" if [ $PLATFORM = "UBUNTU12_64" -o $PLATFORM = "UBUNTU14_64" -o $PLATFORM = "UBUNTU16_64" -o $PLATFORM = "UBUNTU18_64" -o $PLATFORM = "UBUNTU20_64" -o $PLATFORM = "UBUNTU22_64" -o $PLATFORM = "UBUNTU24_64" ]; then STORE_PACKAGES="libreoffice" fi DumpFileDetailsFromPackage() { local pkg_n="$1"; shift LANG="en_US.UTF-8" LANGUAGE="en_US" dpkg-query -W -f='${package}_${Version}_${Architecture}.deb\n' "$pkg_n" } LocalPackageDepList() { local pkg_f="$1"; shift; LANG="en_US.UTF-8" LANGUAGE="en_US" \ dpkg -I "$pkg_f" \ | sed -n -e '/Depends:/ { s/.*:\s*//; s/,\s*/\n/g; p; }' \ | sed -n -e '/^zimbra-/ { s/\s*(.*//; p; }' } RepoPackageDepList() { local pkg="$1"; shift; LANG="en_US.UTF-8" LANGUAGE="en_US" \ apt-cache depends "^$pkg$" \ | sed -e 's/[<]\([a-z]\)/\1/g' \ -e 's/\([a-z]\)[>]/\1/g' \ | sed -n -e '/Depends:\s*zimbra-/ { s/.*:\s*//; p; }' } LocatePackageInRepo() { local pkg="$1"; shift; LANG="en_US.UTF-8" LANGUAGE="en_US" \ apt-cache search --names-only "^$pkg" 2>/dev/null } else ISUBUNTU=false REPOINST='yum -y install' REPORM='yum erase -y' PACKAGEINST='rpm -Uvh --replacefiles --replacepkgs' # TODO: This should kept in os-requirement. yum -y install --downloadonly dummyxxxxxxx 2>&1 | grep "no such option: --downloadonly" >/dev/null 2>&1 if [ $? -eq 0 ]; then echo "Installing yum-plugin-downloadonly." yum -y install yum-plugin-downloadonly if [ $? -ne 0 ]; then echo "yum --downloadonly should be available. To continue installation." exit 1; fi fi PACKAGEDOWNLOAD='yum -y install --downloadonly' PACKAGERM='yum -y --disablerepo=* erase -v' PACKAGERMSIMULATE='yum -n --disablerepo=* erase -v' PACKAGEEXT='rpm' PACKAGEQUERY='rpm -q' PACKAGEVERIFY='rpm -K' if [ $PLATFORM = "RHEL6_64" ]; then STORE_PACKAGES="libreoffice libreoffice-headless" fi if [ $PLATFORM = "RHEL7_64" -o $PLATFORM = "RHEL8_64" -o $PLATFORM = "RHEL9_64" ]; then STORE_PACKAGES="libreoffice libreoffice-core" fi DumpFileDetailsFromPackage() { local pkg_n="$1"; shift echo "$(LANG="en_US.UTF-8" LANGUAGE="en_US" rpm -q "$pkg_n").rpm" } LocalPackageDepList() { local pkg_f="$1"; shift; LANG="en_US.UTF-8" LANGUAGE="en_US" \ rpm -q --requires -p "$pkg_f" \ | sed -n -e '/^zimbra-/ { s/\s*[<=>].*//; p; }' } RepoPackageDepList() { local pkg="$1"; shift; LANG="en_US.UTF-8" LANGUAGE="en_US" \ yum deplist "$pkg" \ | sed -n -e '/dependency:\s*zimbra-/ { s/^[^:]*:\s*//; s/\s*[<=>].*//; p }' } LocatePackageInRepo() { local pkg="$1"; shift; LANG="en_US.UTF-8" LANGUAGE="en_US" \ yum --showduplicates list available -q -e 0 "$pkg" 2>/dev/null } fi } ================================================ FILE: rpmconf/Install/install.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # ID=`id -u` if [ "x$ID" != "x0" ]; then echo "Run as root!" exit 1 fi if [ ! -x "/usr/bin/perl" ]; then echo "ERROR: System perl at /usr/bin/perl must be present before installation." exit 1 fi # Function to check for rsyslog or syslog-ng package is_rsyslog_or_syslog_ng_present() { if command -v rsyslogd >/dev/null 2>&1 || command -v syslog-ng >/dev/null 2>&1; then return 0 else echo "ERROR: Zimbra installation requires rsyslog or syslog-ng package to be installed." exit 1 fi } # Perform logging prerequisite check is_rsyslog_or_syslog_ng_present MYDIR="$(cd "$(dirname "$0")" && pwd)" . ./util/utilfunc.sh for i in ./util/modules/*sh; do . $i done UNINSTALL="no" SOFTWAREONLY="no" SKIP_ACTIVATION_CHECK="no" SKIP_UPGRADE_CHECK="no" SKIP_NG_CHECK="no" ALLOW_PLATFORM_OVERRIDE="no" FORCE_UPGRADE="no" usage() { echo "$0 [-r -l -u -s -c type -x -h] [defaultsfile]" echo "" echo "-h|--help Usage" echo "-l|--licensekey License key to install." echo "-r|--restore Restore contents of to localconfig" echo "-s|--softwareonly Software only installation." echo "-u|--uninstall Uninstall ZCS" echo "-x|--skipspacecheck Skip filesystem capacity checks." echo "--beta-support Allows installer to upgrade Network Edition Betas." echo "--platform-override Allows installer to continue on an unknown OS." echo "--skip-activation-check Allows installer to continue if license activation checks fail." echo "--skip-upgrade-check Allows installer to skip upgrade validation checks." echo "--skip-ng-check Allows installer to upgrade by removing NG modules and related data." echo "--force-upgrade Force upgrade to be set to YES. Used if there is package installation failure for remote packages." echo "[defaultsfile] File containing default install values." echo "" exit } validateLicensekey() { local new="$1" if [[ ! "$new" =~ ^[A-Za-z0-9]+$ ]] || (( ${#new} < 18 )) || (( ${#new} > 24 )) || [[ -z "$new" ]]; then echo "Invalid license key entered. The license key should be a non-blank alphanumeric string of 18-24 characters without any special characters!" usage fi } checkSkipActivation() { if [ x"$SKIP_ACTIVATION_CHECK" = "xyes" ]; then if [ ! -d "/opt/zimbra/conf" ]; then mkdir -p /opt/zimbra/conf fi echo "$SKIP_ACTIVATION_CHECK" > /opt/zimbra/conf/skip_activation_check chown zimbra:zimbra /opt/zimbra/conf/skip_activation_check chmod 644 /opt/zimbra/conf/skip_activation_check fi } while [ $# -ne 0 ]; do case $1 in -r|--restore|--config) shift RESTORECONFIG=$1 ;; -l|--licensekey) shift LICENSEKEY=$1 validateLicensekey $LICENSEKEY ;; -u|--uninstall) UNINSTALL="yes" ;; -s|--softwareonly) SOFTWAREONLY="yes" ;; -x|--skipspacecheck) SKIPSPACECHECK="yes" ;; -platform-override|--platform-override) ALLOW_PLATFORM_OVERRIDE="yes" ;; -beta-support|--beta-support) BETA_SUPPORT="yes" ;; -skip-activation-check|--skip-activation-check) SKIP_ACTIVATION_CHECK="yes" ;; -skip-upgrade-check|--skip-upgrade-check) SKIP_UPGRADE_CHECK="yes" ;; -skip-ng-check|--skip-ng-check) SKIP_NG_CHECK="yes" ;; -force-upgrade|--force-upgrade) FORCE_UPGRADE="yes" UPGRADE="yes" ;; -h|-help|--help) usage ;; *) DEFAULTFILE=$1 if [ ! -f "$DEFAULTFILE" ]; then echo "ERROR: Unknown option $DEFAULTFILE" usage fi ;; esac shift done . ./util/globals.sh getPlatformVars mkdir -p $SAVEDIR chown zimbra:zimbra $SAVEDIR 2> /dev/null chmod 750 $SAVEDIR echo "" echo "Operations logged to $LOGFILE" licensefiles=( "/opt/zimbra/conf/ZCSLicense-activated.xml" "/opt/zimbra/conf/ZCSLicensekey" "/opt/zimbra/conf/skip_activation_check" ) for file in "${licensefiles[@]}"; do if [[ -e "$file" ]]; then rm -f "$file" fi done if [ "x$DEFAULTFILE" != "x" ]; then AUTOINSTALL="yes" else AUTOINSTALL="no" fi if [ "x$LICENSEKEY" != "x" ] ; then if [ ! -d "/opt/zimbra/conf" ]; then mkdir -p /opt/zimbra/conf fi echo "$LICENSEKEY" > /opt/zimbra/conf/ZCSLicensekey chown zimbra:zimbra /opt/zimbra/conf/ZCSLicensekey chmod 644 /opt/zimbra/conf/ZCSLicensekey fi checkSkipActivation checkExistingInstall if [ x$UNINSTALL = "xyes" ]; then askYN "Completely remove existing installation?" "N" if [ $response = "yes" ]; then REMOVE="yes" findUbuntuExternalPackageDependencies saveExistingConfig removeExistingInstall fi exit 1 fi displayLicense checkUser root if [ $AUTOINSTALL = "yes" ]; then loadConfig $DEFAULTFILE fi checkRequired installable_platform=$(cat ${MYDIR}/.BUILD_PLATFORM) if [ x"$PLATFORM" = x"$installable_platform" -a x"${ALLOW_PLATFORM_OVERRIDE}" = "xyes" ]; then ALLOW_PLATFORM_OVERRIDE="no" fi if [ x"${ALLOW_PLATFORM_OVERRIDE}" = "xno" ]; then configurePackageServer fi checkPackages if [ $AUTOINSTALL = "no" ]; then setRemove getInstallPackages if [ x"$PLATFORM" != x"$installable_platform" ]; then echo "" echo "You appear to be installing packages on a platform different" echo "than the platform for which they were built." echo "" echo "This platform is $PLATFORM" echo "Packages found: $installable_platform" echo "This may or may not work." echo "" if [ x"${ALLOW_PLATFORM_OVERRIDE}" = "xyes" ]; then echo "Using packages for a platform in which they were not designed for" echo "may result in an installation that is NOT usable. Your support" echo "options may be limited if you choose to continue." echo "You will also be responsible for configuring the system to point" echo "at an appropriate package repository for third party." echo "" askYN "Install anyway?" "N" if [ $response = "no" ]; then echo "Exiting..." exit 1 fi else echo "Installation can not continue without manual override." echo "You can override this safety check with $0 --platform-override" echo "" echo "WARNING: Bypassing this check may result in an install or" echo "upgrade that is NOT usable." echo "" exit 1 fi fi verifyExecute else checkVersionMatches if [ $VERSIONMATCH = "no" ]; then if [ $UPGRADE = "yes" ]; then echo "" echo "###ERROR###" echo "" echo "There is a mismatch in the versions of the installed schema" echo "or index and the version included in this package" echo "" echo "Automatic upgrade cancelled" echo "" exit 1 fi fi fi D=`date +%s` echo "${D}: INSTALL SESSION START" >> /opt/zimbra/.install_history installPackages D=`date +%s` echo "${D}: INSTALL SESSION COMPLETE" >> /opt/zimbra/.install_history if [ x$RESTORECONFIG != "x" ]; then SAVEDIR=$RESTORECONFIG fi if [ x$SAVEDIR != "x" -a x$REMOVE = "xno" ]; then setDefaultsFromExistingConfig fi if [ $UPGRADE = "yes" ]; then restoreExistingConfig restoreCerts # deprecated by move of zimlets to /opt/zimbra/zimlets-deployed which isn't removed on upgrade #restoreZimlets fi if [ "x$LICENSEKEY" != "x" ] ; then if [ ! -d "/opt/zimbra/conf" ]; then mkdir -p /opt/zimbra/conf fi echo "$LICENSEKEY" > /opt/zimbra/conf/ZCSLicensekey chown zimbra:zimbra /opt/zimbra/conf/ZCSLicensekey chmod 644 /opt/zimbra/conf/ZCSLicensekey fi checkSkipActivation if [ $SOFTWAREONLY = "yes" ]; then echo "" echo "Software Installation complete!" echo "" echo "Operations logged to $LOGFILE" echo "" exit 0 fi if [ -e "$LOGFILE" ]; then LOG_DIR="/opt/zimbra/log" if [ ! -d "$LOG_DIR" ]; then mkdir -p "$LOG_DIR" chown zimbra:zimbra "$LOG_DIR" fi echo "Copying $LOGFILE to $LOG_DIR" cp -f $LOGFILE $LOG_DIR/ chown zimbra:zimbra "$LOG_DIR/$(basename "$LOGFILE")" fi # # Installation complete, now configure # if [ "x$DEFAULTFILE" != "x" ]; then /opt/zimbra/libexec/zmsetup.pl -c $DEFAULTFILE else /opt/zimbra/libexec/zmsetup.pl fi RC=$? if [ $RC -ne 0 ]; then exit $RC fi ================================================ FILE: rpmconf/Install/postinstall.pm ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package postinstall; sub configure { if (main::isEnabled("zimbra-ldap")) { main::runAsZimbra ("${main::ZMPROV} mcf zimbraComponentAvailable ''"); main::runAsZimbra ("zmlocalconfig -u trial_expiration_date"); } # we temporary set this to true during the install/upgrade main::setLocalConfig("ssl_allow_untrusted_certs", "false") if $main::newinstall; if (main::isEnabled("zimbra-mta") && $main::newinstall) { my @mtalist = main::getAllServers("mta"); if (scalar(@mtalist) gt 1) { main::setLocalConfig("zmtrainsa_cleanup_host", "false") } else { main::setLocalConfig("zmtrainsa_cleanup_host", "true") } } } sub notifyZimbra { if (!defined ($main::options{c}) && 1) { if (main::askYN("\nYou have the option of notifying Zimbra of your installation.\nThis helps us to track the uptake of the Zimbra Collaboration Server.\nThe only information that will be transmitted is:\n\tThe VERSION of zcs installed (${main::curVersion}_${main::platform})\n\tThe ADMIN EMAIL ADDRESS created ($main::config{CREATEADMIN})\n\nNotify Zimbra of your installation?", "Yes") eq "yes") { if (open NOTIFY, "/opt/zimbra/libexec/zmnotifyinstall ${main::curVersion}_${main::platform} $main::config{CREATEADMIN} |") { while () { main::progress ("$_"); } close NOTIFY; #main::progress ("Notification complete!\n"); } else { #main::progress ("ERROR: Notification failed!\n\n"); } } else { main::progress ("Notification skipped\n"); } } } 1 ================================================ FILE: rpmconf/Install/preinstall.pm ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2006, 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package preinstall; sub mainMenuExtensions { my ($mm, $i) = (@_); return $i; } 1 ================================================ FILE: rpmconf/Install/test.pl ================================================ ================================================ FILE: rpmconf/Install/zmsetup.pl ================================================ #!/usr/bin/perl # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # use strict; use lib "/opt/zimbra/libexec"; use lib "/opt/zimbra/common/lib/perl5"; use Zimbra::Util::Common; use Zimbra::Util::Timezone; use Net::LDAP; use IPC::Open3; use Cwd; use Time::localtime qw(ctime); use File::Path qw(make_path); $|=1; # don't buffer stdout our $platform = qx(/opt/zimbra/libexec/get_plat_tag.sh); chomp $platform; my $logFileName = "zmsetup.".getDateStamp().".log"; my $logfile = "/tmp/".$logFileName; open LOGFILE, ">$logfile" or die "Can't open $logfile: $!\n"; unlink("/tmp/zmsetup.log") if (-e "/tmp/zmsetup.log"); symlink($logfile, "/tmp/zmsetup.log"); my $ol = select (LOGFILE); select ($ol); $| = 1; progress("Operations logged to $logfile\n"); our $ZMPROV = "/opt/zimbra/bin/zmprov -r -m -l"; our $SU = "su - zimbra -c "; my $filename="/opt/zimbra/conf/localconfig.xml"; my $uid = (stat $filename)[4]; my $user = (getpwuid $uid)[0]; my $license_file = "/opt/zimbra/conf/ZCSLicensekey"; my $skip_activation_file = "/opt/zimbra/conf/skip_activation_check"; my $skip_activation_check = `cat $skip_activation_file 2>/dev/null`; chomp($skip_activation_check); if ($user ne "zimbra") { progress ("\n\nERROR\n\n"); progress ("/opt/zimbra/conf/localconfig.xml is not owned by zimbra\n"); progress ("This will cause installation failure.\n"); exit (1); } use preinstall; use postinstall; use zmupgrade; use Getopt::Std; use Net::DNS::Resolver; use NetAddr::IP; our %options = (); our %config = (); our %loaded = (); our %saved = (); my @packageList = ( "zimbra-core", "zimbra-ldap", "zimbra-logger", "zimbra-mta", "zimbra-dnscache", "zimbra-snmp", "zimbra-store", "zimbra-apache", "zimbra-spell", "zimbra-convertd", "zimbra-memcached", "zimbra-proxy", "zimbra-archiving", "zimbra-imapd", "zimbra-onlyoffice", "zimbra-license-daemon", ); my %packageServiceMap = ( amavis => "zimbra-mta", antivirus => "zimbra-mta", antispam => "zimbra-mta", opendkim => "zimbra-mta", cbpolicyd => "zimbra-mta", dnscache => "zimbra-dnscache", imapd => "zimbra-imapd", mta => "zimbra-mta", logger => "zimbra-logger", mailbox => "zimbra-store", snmp => "zimbra-snmp", ldap => "zimbra-ldap", spell => "zimbra-spell", stats => "zimbra-core", 'vmware-ha' => "zimbra-core", memcached => "zimbra-memcached", proxy => "zimbra-proxy", archiving => "zimbra-archiving", convertd => "zimbra-convertd", service => "zimbra-store", zimbra => "zimbra-store", zimbraAdmin => "zimbra-store", zimlet => "zimbra-store", onlyoffice => "zimbra-onlyoffice", 'license-daemon' => "zimbra-license-daemon", ); my @webappList = ( "service", "zimbra", "zimbraAdmin", "zimlet", ); my %installedPackages = (); our %installedWebapps = (); my %prevInstalledPackages = (); my %enabledPackages = (); my %enabledServices = (); my %installStatus = (); our %configStatus = (); our %migratedStatus= (); my $prevVersion = ""; our $curVersion = ""; my ($prevVersionMinor,$prevVersionMajor,$prevVersionMicro,$prevVersionBuild); my ($curVersionMinor,$curVersionMajor,$curVersionMicro,$curVersionMicroMicro,$curVersionType,$curVersionBuild); our $newinstall = 1; chomp (my $ldapSchemaVersion = do { local $/ = undef; open my $fh, "<", "/opt/zimbra/conf/zimbra-attrs-schema" or die "could not open /opt/zimbra/conf/zimbra-attrs-schema: $!"; <$fh>; }); my $ldapConfigured = 0; my $haveSetLdapSchemaVersion = 0; my $ldapRunning = 0; my $sqlConfigured = 0; my $sqlRunning = 0; my $loggerSqlConfigured = 0; my $loggerSqlRunning = 0; my @installedServiceList = (); my @enabledServiceList = (); my $ldapRootPassChanged = 0; my $ldapAdminPassChanged = 0; my $ldapRepChanged = 0; my $ldapPostChanged = 0; my $ldapAmavisChanged = 0; my $ldapNginxChanged = 0; my $ldapBesSearcherChanged = 0; my $ldapReplica = 0; my $starttls = 0; my $needNewCert = ""; my $ssl_cert_type = "self"; my @ssl_digests = ("ripemd160","sha","sha1","sha224","sha256","sha384","sha512"); my @interfaces = (); ($>) and usage(); getopts("c:hd", \%options) or usage(); my $debug = $options{d}; usage() if ($options{h}); getInstallStatus(); if ($0 =~ /testMenu/) { #delete $installedPackages{"zimbra-ldap"}; #delete $installedPackages{"zimbra-mta"}; getInstalledPackages(); setDefaults(); setLdapDefaults(); setEnabledDependencies(); mainMenu(); exit; } if (isInstalled("zimbra-ldap")) { if ($newinstall || ! -f "/opt/zimbra/data/ldap/config/cn\=config.ldif") { installLdapConfig(); } } if(isInstalled("zimbra-ldap")) { installLdapSchema(); } if (! $newinstall ) { # zimbra-openjdk-cacerts replaces OZC/lib/jvm/java/jre/lib/security/cacerts # (re)import our CA cert to reestablish our CA trust if ( -f "/opt/zimbra/conf/ca/ca.pem" ) { progress("Adding /opt/zimbra/conf/ca/ca.pem to cacerts\n"); main::runAsZimbra("/opt/zimbra/bin/zmcertmgr addcacert /opt/zimbra/conf/ca/ca.pem"); } # if we're an upgrade, run the upgrader... if ($prevVersion eq "") { $prevVersion = $curVersion; } if (($prevVersion ne $curVersion )) { progress ("Upgrading from $prevVersion to $curVersion\n"); open (H, ">>/opt/zimbra/.install_history"); print H time(),": CONFIG SESSION START\n"; # This is the postinstall config configLog ("BEGIN"); if (zmupgrade::upgrade($prevVersion, $curVersion)){ progress ("UPGRADE FAILED - exiting.\n"); exit 1; } else { progress ("Upgrade complete.\n\n"); } } } getInstalledPackages(); # This is somewhat of a catch-22. # We can't check ldap to see if it is enabled or not # prior to upgrade, because ldap may not be functional. # Long term, we need to split out zmupgrade.pm into # per-package upgrade scripts, rather than the monolithic # monstrosity it is now. unless (isEnabled("zimbra-core")) { progress("zimbra-core must be enabled."); exit 1; } getInstalledWebapps(); if ($options{d}) { foreach my $pkg (keys %installedPackages) { detail("Package $pkg is installed"); } foreach my $pkg (keys %enabledPackages) { detail("Package $pkg is $enabledPackages{$pkg}"); } } setDefaults(); setDefaultsFromLocalConfig() if (! $newinstall); setEnabledDependencies(); checkPortConflicts(); getSystemStatus(); startLdap() if ($ldapConfigured); if (!$newinstall) { my $rc = runAsZimbra ("/opt/zimbra/libexec/zmldapupdateldif"); } if ($ldapConfigured || (($config{LDAPHOST} ne $config{HOSTNAME}) && ldapIsAvailable())) { setLdapDefaults(); getAvailableComponents(); } if ($options{c}) { loadConfig ($options{c}); applyConfig(); } else { if ($configStatus{BEGIN} eq "CONFIGURED" && $configStatus{END} ne "CONFIGURED") { resumeConfiguration(); } if (!$newinstall) { my $m = createMainMenu(); if (checkMenuConfig($m)) { applyConfig(); } } mainMenu(); } setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersion', $curVersion); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMajor', $curVersionMajor); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMinor', $curVersionMinor); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMicro', $curVersionMicroMicro); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionType', $curVersionType); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionBuild', $curVersionBuild); close LOGFILE; chmod 0600, $logfile; if (-d "/opt/zimbra/log") { main::progress("Moving $logfile to /opt/zimbra/log\n"); system("cp -f $logfile /opt/zimbra/log/"); system("chown zimbra:zimbra /opt/zimbra/log/$logFileName"); } ################################################################ # End Main ################################################################ ################################################################ # Subroutines ################################################################ sub usage { ($>) and print STDERR "Warning: $0 must be run as root!\n\n"; print STDERR "Usage: $0 [-h] [-c ]\n"; print STDERR "\t-h: display this help message\n"; print STDERR "\t-c: configure with values in \n\n"; #print STDERR "\t-l: install license in \n\n"; exit 1; } sub progress { my $msg = shift; print "$msg"; my ($sub,$line) = (caller(1))[3,2]; $msg = "$sub:$line $msg" if $options{d}; detail ($msg); } sub detail { my $msg = shift; my ($sub,$line) = (caller(1))[3,2]; my $date = ctime(); $msg =~ s/\n$//; $msg = "$sub:$line $msg" if $options{d}; open(LOG, ">>$logfile"); print LOG "$date $msg\n"; close(LOG); #qx(echo "$date $msg" >> $logfile); } sub defineInstallWebapps { if (!defined $config{INSTALL_WEBAPPS}) { $config{INSTALL_WEBAPPS} = "zimlet"; if ($config{SERVICEWEBAPP} eq "yes") { $config{INSTALL_WEBAPPS} = "service $config{INSTALL_WEBAPPS}"; } if ($config{UIWEBAPPS} eq "yes") { $config{INSTALL_WEBAPPS} = "$config{INSTALL_WEBAPPS} zimbra zimbraAdmin"; } } } sub saveConfig { my $fname = "/opt/zimbra/config.$$"; if (!(defined ($options{c})) && $newinstall ) { $fname = askNonBlank ("Save config in file:", $fname); } if (open CONF, ">$fname") { progress ("Saving config in $fname..."); foreach (sort keys %config) { # Don't write passwords or previous INSTALL_PACKAGES if (/PASS|INSTALL_PACKAGES/) {next;} print CONF qq($_="$config{$_}"\n); } print CONF qq(INSTALL_PACKAGES="); foreach (@packageList) { my $el = $_; if (grep (/$el/, keys %installedPackages)) { print CONF "$_ "; } } print CONF qq("\n); close CONF; chmod 0600, $fname; progress ("done.\n"); } else { progress( "Can't open $fname: $!\n"); } } sub loadConfig { my $filename = shift; open (CONF, $filename) or die "Can't open $filename: $!"; my @lines = ; close CONF; foreach (@lines) { chomp; my ($k, $v) = split ('=', $_, 2); $v=~s/"//g; $config{$k} = $v; } $config{ALLOWSELFSIGNED} = "true"; } sub checkPortConflicts { progress ( "Checking for port conflicts\n" ); my %needed = ( 25 => 'zimbra-mta', 53 => 'zimbra-dnscache', 80 => 'zimbra-store', 110 => 'zimbra-store', 143 => 'zimbra-store', 389 => 'zimbra-ldap', 443 => 'zimbra-store', 636 => 'zimbra-ldap', 993 => 'zimbra-store', 995 => 'zimbra-store', 7025 => 'zimbra-store', 7071 => 'zimbra-store', 7072 => 'zimbra-store', 7047 => 'zimbra-convertd', 7306 => 'zimbra-store', 7307 => 'zimbra-store', 7780 => 'zimbra-spell', 8143 => 'zimbra-imapd', 8993 => 'zimbra-imapd', 8465 => 'zimbra-mta', 10024 => 'zimbra-mta', 10025 => 'zimbra-mta', 10026 => 'zimbra-mta', 10027 => 'zimbra-mta', 10028 => 'zimbra-mta', 10029 => 'zimbra-mta', 10030 => 'zimbra-mta', 7084 => 'zimbra-onlyoffice', 7085 => 'zimbra-onlyoffice', ); open PORTS, "netstat -an | egrep '^tcp' | grep LISTEN | awk '{print \$4}' | sed -e 's/.*://' |"; my @ports = ; close PORTS; chomp @ports; my $any = 0; foreach (@ports) { if (defined ($needed{$_}) && isEnabled($needed{$_})) { # don't report ldap conflicts on upgrade # 14438 unless ($needed{$_} eq "zimbra-ldap" && $newinstall == 0) { $any = 1; progress ( "Port conflict detected: $_ ($needed{$_})\n" ); } } } if (!$options{c}) { if ($any) { ask("Port conflicts detected! - Press Enter/Return key to continue", ""); } } } sub isComponentAvailable { my $component = shift; detail("checking isComponentAvailable $component"); # if its already defined return; if (exists $main::loaded{components}{$component}) { return 1; } if ($ldapConfigured || (($config{LDAPHOST} ne $config{HOSTNAME}) && ldapIsAvailable())) { getAvailableComponents(); } if (exists $main::loaded{components}{$component}) { detail("Component $component is available."); return 1; } else { detail("Component $component is not available."); return 0; } } sub getAvailableComponents { detail("Getting available components"); open(ZM, "$ZMPROV gcf zimbraComponentAvailable 2> /dev/null|") or return undef; while () { chomp; if (/^zimbraComponentAvailable: (\S+)/) { $main::loaded{components}{$1} = "zimbraComponentAvailable"; } } close(ZM) or return undef; } sub getDateStamp() { my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time()); $year = 1900+$year; $sec = sprintf("%02d", $sec); $min = sprintf("%02d", $min); $hour = sprintf("%02d", $hour); $mday = sprintf("%02d", $mday); $mon = sprintf("%02d", $mon+1); my $stamp = "$year$mon$mday-$hour$min$sec"; return $stamp; } sub getInstalledPackages { detail("Getting installed packages"); foreach my $p (@packageList) { if (isInstalled($p)) { $installedPackages{$p} = $p; } } # get list of previously installed packages on upgrade if ($newinstall == 0) { $config{zimbra_server_hostname} = getLocalConfig ("zimbra_server_hostname") if ($config{zimbra_server_hostname} eq ""); detail ("DEBUG: zimbra_server_hostname=$config{zimbra_server_hostname}") if $options{d}; $config{ldap_url} = getLocalConfig ("ldap_url") if ($config{ldap_url} eq ""); detail ("DEBUG: ldap_url=$config{ldap_url}") if $options{d}; if (index($config{ldap_url}, "/".$config{zimbra_server_hostname}) != -1) { detail ("zimbra_server_hostname contained in ldap_url checking ldap status"); if (startLdap()) {return 1;} } else { detail ("zimbra_server_hostname not in ldap_url not starting slapd"); } detail("Getting installed services from ldap"); open(ZMPROV, "$ZMPROV gs $config{zimbra_server_hostname}|"); while () { chomp; if (/zimbraServiceInstalled:\s(.*)/) { my $service = $1; if ($service eq "imapproxy") { $service = "proxy"; } if (exists $packageServiceMap{$service}) { detail ("Marking $service as previously installed.") if ($debug); $prevInstalledPackages{$packageServiceMap{$service}} = "Installed"; } else { progress("WARNING: Unknown package installed for $service.\n"); } } else { detail ("DEBUG: skipping not zimbraServiceInstalled => $_") if $debug; } } } } sub getInstalledWebapps { detail("Determining installed web applications"); my $webappsDir = "/opt/zimbra/jetty/webapps"; foreach my $app (@webappList) { if (($newinstall && -d "$webappsDir/$app") || (!$newinstall && isServiceEnabled($app))) { $installedWebapps{$app}="Enabled"; detail("Web application $app is enabled."); } else { if ($newinstall || (!$newinstall && $installedWebapps{$app} ne "Enabled")) { $installedWebapps{$app}="Disabled"; } } } if (!$newinstall && !defined($config{INSTALL_WEBAPPS})) { foreach my $app (%installedWebapps) { if ($installedWebapps{$app} eq "Enabled") { $config{INSTALL_WEBAPPS}="$app $config{INSTALL_WEBAPPS}"; } } } } sub isServiceEnabled { my $service = shift; if (defined ($enabledServices{$service})) { if ($enabledServices{$service} eq "Enabled") { detail ("$service is enabled"); return 1; } else { detail("$service is not enabled"); return undef; } } else { detail("$service not in enabled cache"); } return undef; } sub isEnabled { my $package = shift; detail("checking isEnabled $package"); # if its already defined return; if (defined $enabledPackages{$package}) { if ($enabledPackages{$package} eq "Enabled") { detail("$package is enabled"); return 1; } else { detail("$package is not enabled"); return undef; } } else { detail("$package not in enabled cache"); my $packages = join(" ", keys %enabledPackages); detail("enabled packages $packages"); } # lookup service in ldap if ($newinstall == 0) { $config{zimbra_server_hostname} = getLocalConfig ("zimbra_server_hostname") if ($config{zimbra_server_hostname} eq ""); detail ("DEBUG: zimbra_server_hostname=$config{zimbra_server_hostname}") if $options{d}; $config{ldap_url} = getLocalConfig ("ldap_url") if ($config{ldap_url} eq ""); detail ("DEBUG: ldap_url=$config{ldap_url}") if $options{d}; if (index($config{ldap_url}, "/".$config{zimbra_server_hostname}) != -1) { detail ("zimbra_server_hostname contained in ldap_url checking ldap status"); if (startLdap()) {return 1;} } else { detail ("zimbra_server_hostname not in ldap_url not starting slapd"); } detail("Getting enabled services from ldap"); $enabledPackages{"zimbra-core"} = "Enabled" if (isInstalled("zimbra-core")); open(ZMPROV, "$ZMPROV gs $config{zimbra_server_hostname}|"); while () { chomp; if (/zimbraServiceEnabled:\s(.*)/) { my $service = $1; if ($service eq "imapproxy") { $service = "proxy"; } if (exists $packageServiceMap{$service}) { detail ("Marking $service as an enabled service.") if ($debug); $enabledPackages{$packageServiceMap{$service}} = "Enabled"; $enabledServices{$service} = "Enabled"; } else { progress("WARNING: Unknown package installed for $service.\n"); } } else { detail ("DEBUG: skipping not zimbraServiceEnabled => $_") if $debug; } } foreach my $p (@packageList) { if (isInstalled($p) and not defined $prevInstalledPackages{$p}) { detail("Marking $p as installed. Services for $p will be enabled."); $enabledPackages{$p} = "Enabled"; } elsif (isInstalled($p) and not defined $enabledPackages{$p}) { detail("Marking $p as disabled."); $enabledPackages{$p} = "Disabled"; } } close(ZMPROV); } else { detail("Newinstall enabling all installed packages"); foreach my $p (@packageList) { if (isInstalled($p)) { unless ($enabledPackages{$p} eq "Disabled") { detail("Enabling $p"); $enabledPackages{$p} = "Enabled" } } } } $enabledPackages{$package} = "Disabled" if ($enabledPackages{$package} ne "Enabled"); return ($enabledPackages{$package} eq "Enabled" ? 1 : 0); } sub isInstalled { my $pkg = shift; my $pkgQuery; my $good = 0; if ($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) { $pkgQuery = "dpkg -s $pkg"; } else { $pkgQuery = "rpm -q $pkg"; } my $rc = 0xffff & system ("$pkgQuery > /dev/null 2>&1"); $rc >>= 8; if (($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) && $rc == 0 ) { $good = 1; $pkgQuery = "dpkg -s $pkg | egrep '^Status: ' | grep 'not-installed'"; $rc = 0xffff & system ("$pkgQuery > /dev/null 2>&1"); $rc >>= 8; return ($rc == $good); } else { return ($rc == $good); } } sub genRandomPass { open RP, "/opt/zimbra/bin/zmjava com.zimbra.common.util.RandomPassword -l 8 10|" or die "Can't generate random password: $!\n"; my $rp = ; close RP; chomp $rp; return $rp; } sub getSystemStatus { if (isEnabled("zimbra-ldap")) { if (-f "/opt/zimbra/data/ldap/mdb/db/data.mdb") { $ldapConfigured = 1; $ldapRunning = 0xffff & system("/opt/zimbra/bin/ldap status > /dev/null 2>&1"); if ($ldapRunning) { $ldapRunning = 0; } else { $ldapRunning = 1; } # Mac on x86 choked on this line? #$ldapRunning = ($ldapRunning)?0:1; } else { $config{DOCREATEDOMAIN} = "yes"; } } if (isEnabled("zimbra-store")) { if (-d "/opt/zimbra/db/data/zimbra") { $sqlConfigured = 1; $sqlRunning = 0xffff & system("/opt/zimbra/bin/mysqladmin status > /dev/null 2>&1"); $sqlRunning = ($sqlRunning)?0:1; } if ($newinstall) { $config{DOCREATEADMIN} = "yes"; $config{DOTRAINSA} = "yes"; } } if (isEnabled("zimbra-logger")) { if (-d "/opt/zimbra/logger/db/data/zimbra_logger") { $loggerSqlConfigured = 1; $loggerSqlRunning = 0xffff & system("/opt/zimbra/bin/logmysqladmin status > /dev/null 2>&1"); $loggerSqlRunning = ($loggerSqlRunning)?0:1; } } if (isEnabled("zimbra-mta")) { $config{SMTPHOST} = $config{HOSTNAME} if ($config{SMTPHOST} eq ""); } } sub getAllServers { my ($service) = @_; my @servers; detail("Running $ZMPROV gas $service"); open(ZMPROV, "$ZMPROV gas $service 2>/dev/null|"); chomp(@servers = ); close(ZMPROV); return @servers; } sub getLdapAccountValue($$) { my ($attrib,$sub) = @_; my ($val,$err); my $sec="acct"; if (exists $main::loaded{$sec}{$sub}{$attrib}) { $val = $main::loaded{$sec}{$sub}{$attrib}; detail("Returning cached config attribute for Account $sub: $attrib=$val"); return $val; } my ($rfh,$wfh,$efh,$cmd,$rc); $rfh = new FileHandle; $wfh = new FileHandle; $efh = new FileHandle; $cmd = "$ZMPROV ga $sub"; my $pid = open3($wfh,$rfh,$efh,$cmd); unless(defined($pid)) { return undef; } close $wfh; my @d = <$rfh>; while (scalar(@d) > 0) { chomp(my $line = shift(@d)); my ($k, $v) = $line =~ m/^(\w+):\s(.*)/; while ($d[0] !~ m/^\w+:\s.*/ && scalar(@d) > 0) { chomp($v .= shift(@d)); } if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) { if (exists $main::loaded{$sec}{$sub}{$k}) { $main::loaded{$sec}{$sub}{$k}="$main::loaded{$sec}{$sub}{$k}\n$v"; } else { $main::loaded{$sec}{$sub}{$k}="$v"; } } } chomp($err = join "", <$efh>); detail("$err") if (length($err) > 0); waitpid($pid,0); if ($? == -1) { # failed to execute return undef; } elsif ($? & 127) { # died with signal return undef; } else { $rc = $? >> 8; return undef if ($rc != 0); } $val=$main::loaded{$sec}{$sub}{$attrib}; $main::loaded{$sec}{$sub}{zmsetuploaded}=1; detail("Returning retrieved account config attribute for $sub: $attrib=$val"); return $val; } sub getLdapCOSValue { my ($attrib,$sub) = @_; $sub = "default" if ($sub eq ""); my $sec="gc"; my ($val,$err); if (exists $main::loaded{$sec}{$sub}{$attrib}) { $val=$main::loaded{$sec}{$sub}{$attrib}; detail("Returning cached cos config attribute for $sub: $attrib=$val"); return $val; } my ($rfh,$wfh,$efh,$cmd,$rc); $rfh = new FileHandle; $wfh = new FileHandle; $efh = new FileHandle; $cmd = "$ZMPROV gc $sub"; my $pid = open3($wfh,$rfh,$efh, $cmd); unless(defined($pid)) { return undef; } close $wfh; my @d = <$rfh>; while (scalar(@d) > 0) { chomp(my $line = shift(@d)); my ($k, $v) = $line =~ m/^(\w+):\s(.*)/; while ($d[0] !~ m/^\w+:\s.*/ && scalar(@d) > 0) { chomp($v .= shift(@d)); } if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) { if (exists $main::loaded{$sec}{$sub}{$k}) { $main::loaded{$sec}{$sub}{$k}="$main::loaded{$sec}{$sub}{$k}\n$v"; } else { $main::loaded{$sec}{$sub}{$k}="$v"; } } } chomp($err = join "", <$efh>); detail("$err") if (length($err) > 0); waitpid($pid,0); if ($? == -1) { # failed to execute close $rfh; close $efh; return undef; } elsif ($? & 127) { # died with signal close $rfh; close $efh; return undef; } else { $rc = $? >> 8; close $rfh; close $efh; return undef if ($rc != 0); } close $rfh; close $efh; $val=$main::loaded{$sec}{$sub}{$attrib}; $main::loaded{$sec}{$sub}{zmsetuploaded}=1; detail("Returning retrieved cos config attribute for $sub: $attrib=$val"); return $val; } sub getLdapConfigValue { my $attrib = shift; my ($val,$err); my $sec="gcf"; my $sub=$sec; if (exists $main::loaded{$sec}{$sub}{$attrib}) { $val=$main::loaded{$sec}{$sub}{$attrib}; detail("Returning cached global config attribute: $attrib=$val"); return $val; } my ($rfh,$wfh,$efh,$cmd,$rc); $rfh = new FileHandle; $wfh = new FileHandle; $efh = new FileHandle; $cmd = "$ZMPROV gacf"; my $pid = open3($wfh,$rfh,$efh, $cmd); unless(defined($pid)) { return undef; } close $wfh; my @d = <$rfh>; while (scalar(@d) > 0) { chomp(my $line = shift(@d)); my ($k, $v) = $line =~ m/^(\w+):\s(.*)/; while ($d[0] !~ m/^\w+:\s.*/ && scalar(@d) > 0) { chomp($v .= shift(@d)); } if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) { if (exists $main::loaded{$sec}{$sub}{$k}) { $main::loaded{$sec}{$sub}{$k}="$main::loaded{$sec}{$sub}{$k}\n$v"; } else { $main::loaded{$sec}{$sub}{$k}="$v"; } } } chomp($err = join "", <$efh>); detail("$err") if (length($err) > 0); waitpid($pid,0); if ($? == -1) { # failed to execute close $rfh; close $efh; return undef; } elsif ($? & 127) { # died with signal close $rfh; close $efh; return undef; } else { $rc = $? >> 8; close $rfh; close $efh; return undef if ($rc != 0); } close $rfh; close $efh; $val=$main::loaded{$sec}{$sub}{$attrib}; $main::loaded{$sec}{$sub}{zmsetuploaded}=1; detail("Returning retrieved global config attribute $attrib=$val"); return $val; } sub getLdapDomainValue { my ($attrib,$sub) = @_; $sub = $config{zimbraDefaultDomainName} if ($sub eq ""); return undef if ($sub eq ""); my $sec="domain"; my ($val,$err); if (exists $main::loaded{$sec}{$sub}{$attrib}) { $val = $main::loaded{$sec}{$sub}{$attrib}; detail("Returning cached domain config attribute for $sub: $attrib=$val"); return $val; } my ($rfh,$wfh,$efh,$cmd,$rc); $rfh = new FileHandle; $wfh = new FileHandle; $efh = new FileHandle; $cmd = "$ZMPROV gd $sub"; my $pid = open3($wfh,$rfh,$efh, $cmd); unless(defined($pid)) { return undef; } close $wfh; my @d = <$rfh>; while (scalar(@d) > 0) { chomp(my $line = shift(@d)); my ($k, $v) = $line =~ m/^(\w+):\s(.*)/; while ($d[0] !~ m/^\w+:\s.*/ && scalar(@d) > 0) { chomp($v .= shift(@d)); } if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) { if (exists $main::loaded{$sec}{$sub}{$k}) { $main::loaded{$sec}{$sub}{$k}="$main::loaded{$sec}{$sub}{$k}\n$v"; } else { $main::loaded{$sec}{$sub}{$k}="$v"; } } } chomp($err = join "", <$efh>); detail("$err") if (length($err) > 0); waitpid($pid,0); if ($? == -1) { # failed to execute close $rfh; close $efh; return undef; } elsif ($? & 127) { # died with signal close $rfh; close $efh; return undef; } else { $rc = $? >> 8; close $rfh; close $efh; return undef if ($rc != 0); } close $rfh; close $efh; $main::loaded{$sec}{$sub}{zmsetuploaded}=1; $val=$main::loaded{$sec}{$sub}{$attrib}; detail("Returning retrieved domain config attribute for $sub: $attrib=$val"); return $val; } sub getLdapServerValue { my ($attrib,$sub) = @_; $sub = $main::config{HOSTNAME} if ($sub eq ""); my $sec="gs"; my ($val,$err); if (exists $main::loaded{$sec}{$sub}{$attrib}) { $val = $main::loaded{$sec}{$sub}{$attrib}; detail("Returning cached server config attribute for $sub: $attrib=$val"); return $val; } my ($rfh,$wfh,$efh,$cmd,$rc); $rfh = new FileHandle; $wfh = new FileHandle; $efh = new FileHandle; $cmd = "$ZMPROV gs $sub"; my $pid = open3($wfh,$rfh,$efh, $cmd); unless(defined($pid)) { return undef; } close $wfh; my @d = <$rfh>; while (scalar(@d) > 0) { chomp(my $line = shift(@d)); my ($k, $v) = $line =~ m/^(\w+):\s(.*)/; while ($d[0] !~ m/^\w+:\s.*/ && scalar(@d) > 0) { chomp($v .= shift(@d)); } if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) { if (exists $main::loaded{$sec}{$sub}{$k}) { $main::loaded{$sec}{$sub}{$k}="$main::loaded{$sec}{$sub}{$k}\n$v"; } else { $main::loaded{$sec}{$sub}{$k}="$v"; } } } chomp($err = join "", <$efh>); detail("$err") if (length($err) > 0); waitpid($pid,0); if ($? == -1) { # failed to execute close $rfh; close $efh; return undef; } elsif ($? & 127) { # died with signal close $rfh; close $efh; return undef; } else { $rc = $? >> 8; close $rfh; close $efh; return undef if ($rc != 0); } close $rfh; close $efh; $main::loaded{$sec}{$sub}{zmsetuploaded}=1; $val = $main::loaded{$sec}{$sub}{$attrib}; detail("Returning retrieved server config attribute for $sub: $attrib=$val"); return $val; } sub getRealLdapServerValue { my ($attrib,$sub) = @_; $sub = $main::config{HOSTNAME} if ($sub eq ""); my $sec="gsreal"; my ($val,$err); if (exists $main::loaded{$sec}{$sub}{$attrib}) { $val = $main::loaded{$sec}{$sub}{$attrib}; detail("Returning cached server config attribute for $sub: $attrib=$val"); return $val; } my ($rfh,$wfh,$efh,$cmd,$rc); $rfh = new FileHandle; $wfh = new FileHandle; $efh = new FileHandle; $cmd = "$ZMPROV gs -e $sub"; my $pid = open3($wfh,$rfh,$efh, $cmd); unless(defined($pid)) { return undef; } close $wfh; my @d = <$rfh>; while (scalar(@d) > 0) { chomp(my $line = shift(@d)); my ($k, $v) = $line =~ m/^(\w+):\s(.*)/; while ($d[0] !~ m/^\w+:\s.*/ && scalar(@d) > 0) { chomp($v .= shift(@d)); } if (!$main::loaded{$sec}{$sub}{zmsetuploaded} || ($main::loaded{$sec}{$sub}{zmsetuploaded} && $k eq $attrib)) { if (exists $main::loaded{$sec}{$sub}{$k}) { $main::loaded{$sec}{$sub}{$k}="$main::loaded{$sec}{$sub}{$k}\n$v"; } else { $main::loaded{$sec}{$sub}{$k}="$v"; } } } chomp($err = join "", <$efh>); detail("$err") if (length($err) > 0); waitpid($pid,0); if ($? == -1) { # failed to execute close $rfh; close $efh; return undef; } elsif ($? & 127) { # died with signal close $rfh; close $efh; return undef; } else { $rc = $? >> 8; close $rfh; close $efh; return undef if ($rc != 0); } close $rfh; close $efh; $main::loaded{$sec}{$sub}{zmsetuploaded}=1; $val = $main::loaded{$sec}{$sub}{$attrib}; detail("Returning retrieved server config attribute for $sub: $attrib=$val"); return $val; } sub setLdapDefaults { return if exists $config{LDAPDEFAULTSLOADED}; progress ( "Setting defaults from ldap..." ); # # Load server specific attributes only if server exists # my $serverid = getLdapServerValue("zimbraId"); if ($serverid ne "") { $config{zimbraIPMode} = getLdapServerValue("zimbraIPMode"); $config{zimbraDNSMasterIP} = getLdapServerValue("zimbraDNSMasterIP"); $config{zimbraDNSUseTCP} = getLdapServerValue("zimbraDNSUseTCP"); $config{zimbraDNSUseUDP} = getLdapServerValue("zimbraDNSUseUDP"); $config{zimbraDNSTCPUpstream} = getLdapServerValue("zimbraDNSTCPUpstream"); $config{IMAPPORT} = getLdapServerValue("zimbraImapBindPort"); $config{IMAPSSLPORT} = getLdapServerValue("zimbraImapSSLBindPort"); $config{REMOTEIMAPBINDPORT} = getLdapServerValue("zimbraRemoteImapBindPort"); $config{REMOTEIMAPSSLBINDPORT} = getLdapServerValue("zimbraRemoteImapSSLBindPort"); $config{POPPORT} = getLdapServerValue("zimbraPop3BindPort"); $config{POPSSLPORT} = getLdapServerValue("zimbraPop3SSLBindPort"); $config{IMAPPROXYPORT} = getLdapServerValue("zimbraImapProxyBindPort"); $config{IMAPSSLPROXYPORT} = getLdapServerValue("zimbraImapSSLProxyBindPort"); $config{POPPROXYPORT} = getLdapServerValue("zimbraPop3ProxyBindPort"); $config{POPSSLPROXYPORT} = getLdapServerValue("zimbraPop3SSLProxyBindPort"); $config{MAILPROXY} = getLdapServerValue("zimbraReverseProxyMailEnabled"); $config{MODE} = getLdapServerValue("zimbraMailMode"); $config{PROXYMODE} = getLdapServerValue("zimbraReverseProxyMailMode"); $config{HTTPPORT} = getLdapServerValue("zimbraMailPort"); $config{HTTPSPORT} = getLdapServerValue("zimbraMailSSLPort"); $config{HTTPPROXYPORT} = getLdapServerValue("zimbraMailProxyPort"); $config{HTTPSPROXYPORT} = getLdapServerValue("zimbraMailSSLProxyPort"); $config{HTTPPROXY} = getLdapServerValue("zimbraReverseProxyHttpEnabled"); $config{SMTPHOST} = getLdapServerValue("zimbraSmtpHostname"); $config{zimbraReverseProxyLookupTarget} = getLdapServerValue("zimbraReverseProxyLookupTarget") if ($config{zimbraReverseProxyLookupTarget} eq ""); if (isEnabled("zimbra-mta")) { my $tmpval = getLdapServerValue("zimbraMtaMyNetworks"); $config{zimbraMtaMyNetworks} = $tmpval unless ($tmpval eq ""); } } # # Load Global config values # # default domainname $config{zimbraDefaultDomainName} = getLdapConfigValue("zimbraDefaultDomainName"); if ($config{zimbraDefaultDomainName} eq "") { $config{zimbraDefaultDomainName} = $config{CREATEDOMAIN}; } else { $config{CREATEDOMAIN} = $config{zimbraDefaultDomainName}; $config{CREATEADMIN} = "admin\@$config{CREATEDOMAIN}"; } if ($config{SMTPHOST} eq "") { my $smtphost = getLdapConfigValue("zimbraSmtpHostname"); $smtphost =~ s/\n/ /g; $config{SMTPHOST} = $smtphost if ($smtphost ne "localhost"); } $config{TRAINSASPAM} = getLdapConfigValue("zimbraSpamIsSpamAccount"); if ($config{TRAINSASPAM} eq "") { $config{TRAINSASPAM} = "spam.".lc(genRandomPass()).'@'.$config{CREATEDOMAIN}; } $config{TRAINSAHAM} = getLdapConfigValue("zimbraSpamIsNotSpamAccount"); if ($config{TRAINSAHAM} eq "") { $config{TRAINSAHAM} = "ham.".lc(genRandomPass()).'@'.$config{CREATEDOMAIN}; } $config{VIRUSQUARANTINE} = getLdapConfigValue("zimbraAmavisQuarantineAccount"); if ($config{VIRUSQUARANTINE} eq "") { $config{VIRUSQUARANTINE} = "virus-quarantine.".lc(genRandomPass()).'@'.$config{CREATEDOMAIN}; } if (isNetwork() && isEnabled("zimbra-store")) { $config{zimbraBackupReportEmailRecipients} = getLdapConfigValue("zimbraBackupReportEmailRecipients"); $config{zimbraBackupReportEmailRecipients} = $config{CREATEADMIN} if ($config{zimbraBackupReportEmailRecipients} eq ""); $config{zimbraBackupReportEmailSender} = getLdapConfigValue("zimbraBackupReportEmailSender"); $config{zimbraBackupReportEmailSender} = $config{CREATEADMIN} if ($config{zimbraBackupReportEmailSender} eq ""); } $config{zimbraVersionCheckInterval} = getLdapConfigValue("zimbraVersionCheckInterval"); if ($config{zimbraVersionCheckInterval} eq "") { $config{VERSIONUPDATECHECKS}=""; } else { $config{VERSIONUPDATECHECKS} = (($config{zimbraVersionCheckInterval} eq "0") ? "FALSE" : "TRUE"); } $config{zimbraVersionCheckSendNotifications} = getLdapConfigValue("zimbraVersionCheckSendNotifications"); $config{zimbraVersionCheckSendNotifications} = "TRUE" if ($config{zimbraVersionCheckSendNotifications} eq ""); if ($config{zimbraVersionCheckSendNotifications} eq "TRUE") { $config{zimbraVersionCheckServer} = getLdapConfigValue("zimbraVersionCheckServer"); $config{zimbraVersionCheckNotificationEmail} = getLdapConfigValue("zimbraVersionCheckNotificationEmail"); # force confirmation of choice during upgrade if this was never setup before if (!$newinstall && $config{zimbraVersionCheckNotificationEmail} eq "" && !$options{c}) { $config{VERSIONUPDATECHECKS}=""; } $config{zimbraVersionCheckNotificationEmail} = $config{CREATEADMIN} if ($config{zimbraVersionCheckNotificationEmail} eq ""); $config{zimbraVersionCheckNotificationEmailFrom} = getLdapConfigValue("zimbraVersionCheckNotificationEmailFrom"); $config{zimbraVersionCheckNotificationEmailFrom} = $config{CREATEADMIN} if ($config{zimbraVersionCheckNotificationEmailFrom} eq ""); } $config{EphemeralBackendURL} = getLdapConfigValue("zimbraEphemeralBackendURL"); $config{USEEPHEMERALSTORE} = "yes" if ($config{EphemeralBackendURL} ne ""); # get the onlyoffice zimbraDocumentServerHost global config if (isEnabled("zimbra-onlyoffice")) { my $tmpval = getLdapConfigValue("zimbraDocumentServerHost"); $config{ONLYOFFICEHOSTNAME} = $tmpval; } # # Load default COS # $config{USEKBSHORTCUTS} = getLdapCOSValue("zimbraPrefUseKeyboardShortcuts"); $config{zimbraPrefTimeZoneId}=getLdapCOSValue("zimbraPrefTimeZoneId"); $config{zimbraFeatureTasksEnabled}=getLdapCOSValue("zimbraFeatureTasksEnabled"); $config{zimbraFeatureTasksEnabled}="Enabled" if (lc($config{zimbraFeatureTasksEnabled}) eq "true"); $config{zimbraFeatureTasksEnabled}="Disabled" if (lc($config{zimbraFeatureTasksEnabled}) eq "false"); $config{zimbraFeatureBriefcasesEnabled}=getLdapCOSValue("zimbraFeatureBriefcasesEnabled"); $config{zimbraFeatureBriefcasesEnabled}="Enabled" if (lc($config{zimbraFeatureBriefcasesEnabled}) eq "true"); $config{zimbraFeatureBriefcasesEnabled}="Disabled" if (lc($config{zimbraFeatureBriefcasesEnabled}) eq "false"); # # Load default domain values # my $galacct = getLdapDomainValue("zimbraGalAccountId"); $config{ENABLEGALSYNCACCOUNTS}=(($galacct eq "") ? "no" : "yes"); # # Set some sane defaults if values were missing in LDAP # $config{HTTPPORT} = 80 if ($config{HTTPPORT} eq 0); $config{HTTPSPORT} = 443 if ($config{HTTPSPORT} eq 0); $config{MODE} = "https" if ($config{MODE} eq ""); $config{PROXYMODE} = "https" if ($config{PROXYMODE} eq ""); $config{REMOTEIMAPBINDPORT} = 8143 if ($config{REMOTEIMAPBINDPORT} eq 0); $config{REMOTEIMAPSSLBINDPORT} = 8993 if ($config{REMOTEIMAPSSLBINDPORT} eq 0); if (isInstalled("zimbra-proxy") && isEnabled("zimbra-proxy")) { if ($config{MAILPROXY} eq "TRUE") { if ($config{IMAPPORT} == $config{IMAPPROXYPORT} && $config{IMAPPORT} == 143) { $config{IMAPPORT} = 7143; } if ($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT} && $config{IMAPSSLPORT} == 993) { $config{IMAPSSLPORT} = 7993; } if ($config{POPPORT} == $config{POPPROXYPORT} && $config{POPPORT} == 110) { $config{POPPORT} = 7110; } if ($config{POPSSLPORT} == $config{POPSSLPROXYPORT} && $config{POPSSLPORT} == 995) { $config{POPSSLPORT} = 7995; } if ($config{IMAPPORT} == $config{IMAPPROXYPORT} && $config{IMAPPORT} == 7143) { $config{IMAPPROXYPORT} = 143; } if ($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT} && $config{IMAPSSLPORT} == 7993) { $config{IMAPSSLPROXYPORT} = 993; } if ($config{POPPORT} == $config{POPPROXYPORT} && $config{POPPORT} == 7110) { $config{POPPROXYPORT} = 110; } if ($config{POPSSLPORT} == $config{POPSSLPROXYPORT} && $config{POPSSLPORT} == 7995) { $config{POPSSLPROXYPORT} = 995; } } if ($config{HTTPPROXY} eq "TRUE") { if ($config{HTTPPORT} == $config{HTTPPROXYPORT} && $config{HTTPPORT} == 80) { $config{HTTPPORT} = 8080; } if ($config{HTTPSPORT} == $config{HTTPSPROXYPORT} && $config{HTTPSPORT} == 443) { $config{HTTPSPORT} = 8443; } if ($config{HTTPPORT} == $config{HTTPPROXYPORT} && $config{HTTPPORT} == 8080) { $config{HTTPPROXYPORT} = 80; } if ($config{HTTPSPORT} == $config{HTTPSPROXYPORT} && $config{HTTPSPORT} == 8443) { $config{HTTPSPROXYPORT} = 443; } } } else { if ($config{IMAPPORT} == $config{IMAPPROXYPORT} && $config{IMAPPORT} == 143) { $config{IMAPPROXYPORT} = 7143; } if ($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT} && $config{IMAPSSLPORT} == 993) { $config{IMAPSSLPROXYPORT} = 7993; } if ($config{POPPORT} == $config{POPPROXYPORT} && $config{POPPORT} == 110) { $config{POPPROXYPORT} = 7110; } if ($config{POPSSLPORT} == $config{POPSSLPROXYPORT} && $config{POPSSLPORT} == 995) { $config{POPSSLPROXYPORT} = 7995; } if ($config{IMAPPORT} == $config{IMAPPROXYPORT} && $config{IMAPPORT} == 7143) { $config{IMAPPORT} = 143; } if ($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT} && $config{IMAPSSLPORT} == 7993) { $config{IMAPSSLPORT} = 993; } if ($config{POPPORT} == $config{POPPROXYPORT} && $config{POPPORT} == 7110) { $config{POPPORT} = 110; } if ($config{POPSSLPORT} == $config{POPSSLPROXYPORT} && $config{POPSSLPORT} == 7995) { $config{POPSSLPORT} = 995; } if ($config{HTTPPORT} == $config{HTTPPROXYPORT} && $config{HTTPPORT} == 80) { $config{HTTPPROXYPORT} = 8080; } if ($config{HTTPSPORT} == $config{HTTPSPROXYPORT} && $config{HTTPSPORT} == 443) { $config{HTTPSPROXYPORT} = 8443; } if ($config{HTTPPORT} == $config{HTTPPROXYPORT} && $config{HTTPPORT} == 8080) { $config{HTTPPORT} = 80; } if ($config{HTTPSPORT} == $config{HTTPSPROXYPORT} && $config{HTTPSPORT} == 8443) { $config{HTTPSPORT} = 443; } } # # debug output # if ($options{d}) { foreach my $key (sort keys %config) { print "\tDEBUG: $key=$config{$key}\n"; } } $config{LDAPDEFAULTSLOADED}=1; progress ( "done.\n" ); } sub installLdapConfig { my $config_src="/opt/zimbra/common/etc/openldap/zimbra/config"; my $config_dest="/opt/zimbra/data/ldap/config"; if (-d "/opt/zimbra/data/ldap/config") { main::progress("Installing LDAP configuration database..."); qx(mkdir -p $config_dest/cn\=config/olcDatabase\=\{2\}mdb); system("cp -f $config_src/cn\=config.ldif $config_dest/cn\=config.ldif"); system("cp -f $config_src/cn\=config/cn\=module\{0\}.ldif $config_dest/cn\=config/cn\=module\{0\}.ldif"); system("cp -f $config_src/cn\=config/cn\=schema.ldif $config_dest/cn\=config/cn\=schema.ldif"); system("cp -f $config_src/cn\=config/olcDatabase\=\{-1\}frontend.ldif $config_dest/cn\=config/olcDatabase\=\{-1\}frontend.ldif"); system("cp -f $config_src/cn\=config/olcDatabase\=\{0\}config.ldif $config_dest/cn\=config/olcDatabase\=\{0\}config.ldif"); system("cp -f $config_src/cn\=config/olcDatabase\=\{1\}monitor.ldif $config_dest/cn\=config/olcDatabase\=\{1\}monitor.ldif"); system("cp -f $config_src/cn\=config/olcDatabase\=\{2\}mdb.ldif $config_dest/cn\=config/olcDatabase\=\{2\}mdb.ldif"); system("cp -f $config_src/cn\=config/olcDatabase\=\{2\}mdb/olcOverlay\=\{0\}dynlist.ldif $config_dest/cn\=config/olcDatabase\=\{2\}mdb/olcOverlay\=\{0\}dynlist.ldif"); system("cp -f $config_src/cn\=config/olcDatabase\=\{2\}mdb/olcOverlay\=\{1\}unique.ldif $config_dest/cn\=config/olcDatabase\=\{2\}mdb/olcOverlay\=\{1\}unique.ldif"); system("cp -f $config_src/cn\=config/olcDatabase\=\{2\}mdb/olcOverlay\=\{2\}noopsrch.ldif $config_dest/cn\=config/olcDatabase\=\{2\}mdb/olcOverlay\=\{2\}noopsrch.ldif"); qx(chmod 600 $config_dest/cn\=config.ldif); qx(chmod 600 $config_dest/cn\=config/*.ldif); qx(chown -R zimbra:zimbra $config_dest); main::progress("done.\n"); } } sub installLdapSchema { main::runAsZimbra("/opt/zimbra/libexec/zmldapschema 2>/dev/null"); } sub setDefaults { progress ( "Setting defaults..." ) unless $options{d}; # Get the interfaces. # Do this in perl, since it's the same on all platforms. my $ipv4found=0; my $ipv6found=0; open INTS, "/sbin/ifconfig | grep ' addr' |"; foreach () { chomp; if ($_ =~ /inet6/) { next if ($_ =~ /Link/); s/.*inet6 //; s/.*addr: //; s/\/.*//; if ($_ ne "::1") { $ipv6found=1; } } else { s/.*inet //; s/\s.*//; s/[a-zA-Z:]//g; s/^\n//g; next if ($_ eq ""); if ($_ ne "127.0.0.1") { $ipv4found=1; } } push @interfaces, $_; } close INTS; if (-x "/sbin/ip") { open INTS, "/sbin/ip addr| grep ' scope ' |"; foreach () { chomp; if ($_ =~ /inet6/) { next if ($_ =~ /link/); s/.*inet6 //; s/.*addr: //; s/\/.*//; if ($_ ne "::1") { $ipv6found=1; } } else { s/.*inet //; s/\/.*//; s/[a-zA-Z:]//g; s/^\n//g; next if ($_ eq ""); if ($_ ne "127.0.0.1") { $ipv4found=1; } } push @interfaces, $_; } close INTS; } my %seen=(); @interfaces = grep {!$seen{$_}++} @interfaces; $config{EXPANDMENU} = "no"; $config{REMOVE} = "no"; $config{UPGRADE} = "yes"; $config{LDAPPORT} = 389; $config{USESPELL} = "no"; $config{SPELLURL} = ""; $config{IMAPPORT} = 143; $config{IMAPSSLPORT} = 993; $config{POPPORT} = 110; $config{POPSSLPORT} = 995; $config{HTTPPORT} = 80; $config{HTTPSPORT} = 443; $config{ssl_default_digest} = "sha256"; if (!$ipv4found && $ipv6found) { $config{zimbraIPMode} = "ipv6"; } else { $config{zimbraIPMode} = "ipv4"; } $config{JAVAHOME} = "/opt/zimbra/common/lib/jvm/java"; setLocalConfig ("zimbra_java_home", "$config{JAVAHOME}"); $config{HOSTNAME} = lc(qx(hostname --fqdn)); chomp $config{HOSTNAME}; $config{ldap_dit_base_dn_config} = "cn=zimbra" if ($config{ldap_dit_base_dn_config} eq ""); $config{mailboxd_directory} = "/opt/zimbra/mailboxd"; if ( -f "/opt/zimbra/common/jetty_home/start.jar" ) { $config{mailboxd_keystore} = "$config{mailboxd_directory}/etc/keystore"; $config{mailboxd_server} = "jetty"; } elsif ( -f "/opt/zimbra/tomcat/bin/startup.sh" ) { $config{mailboxd_keystore} = "$config{mailboxd_directory}/conf/keystore"; $config{mailboxd_server} = "tomcat"; } else { $config{mailboxd_keystore} = "/opt/zimbra/conf/keystore"; } $config{mailboxd_truststore} = "/opt/zimbra/common/lib/jvm/java/lib/security/cacerts"; $config{mailboxd_keystore_password} = genRandomPass(); $config{mailboxd_truststore_password} = "changeit"; if ( -f "/opt/zimbra/bin/zmimapdctl" ) { $config{imapd_keystore} = "/opt/zimbra/conf/imapd.keystore"; $config{imapd_keystore_password} = $config{mailboxd_keystore_password}; } $config{SMTPHOST} = ""; $config{SNMPTRAPHOST} = $config{HOSTNAME}; $config{DOCREATEDOMAIN} = "no"; $config{CREATEDOMAIN} = $config{HOSTNAME}; $config{DOCREATEADMIN} = "no"; if (isEnabled("zimbra-dnscache")) { my @dnsMasters; my @resolv; if ( -r "/etc/resolv.conf" && -f "/etc/resolv.conf" ) { open(RESOLV, '; close RESOLV; foreach my $line (@resolv) { chomp($line); if ($line =~ /^nameserver /) { if ($line !~ /127.0.0.1/ && $line !~ /::1/) { my ($junk, $tmpip); ($junk, $tmpip) = split(/ /, $line, 2); push(@dnsMasters, $tmpip); } } } } if (scalar(@dnsMasters) > 0) { $config{zimbraDNSMasterIP} = join(' ', @dnsMasters); } else { $config{zimbraDNSMasterIP} = ""; } $config{zimbraDNSUseTCP} = "yes"; $config{zimbraDNSUseUDP} = "yes"; $config{zimbraDNSTCPUpstream} = "no"; } if (isEnabled("zimbra-store")) { progress "setting defaults for zimbra-store.\n" if $options{d}; $config{DOCREATEADMIN} = "yes" if $newinstall; $config{DOTRAINSA} = "yes"; $config{SERVICEWEBAPP} = "yes"; $config{UIWEBAPPS} = "yes"; $config{zimbraReverseProxyLookupTarget} = "TRUE" if $newinstall; $config{zimbraMailProxy} = "TRUE" if $newinstall; $config{zimbraWebProxy} = "TRUE" if $newinstall; # default values for upgrades if ($config{TRAINSASPAM} eq "") { $config{TRAINSASPAM} = "spam.".lc(genRandomPass()); $config{TRAINSASPAM} .= '@'.$config{CREATEDOMAIN}; } if ($config{TRAINSAHAM} eq "") { $config{TRAINSAHAM} = "ham.".lc(genRandomPass()); $config{TRAINSAHAM} .= '@'.$config{CREATEDOMAIN}; } if ($config{VIRUSQUARANTINE} eq "") { $config{VIRUSQUARANTINE} = "virus-quarantine.".lc(genRandomPass()); $config{VIRUSQUARANTINE} .= '@'.$config{CREATEDOMAIN}; } if (!$newinstall) { $config{zimbraFeatureBriefcasesEnabled} = "Enabled" if ($config{zimbraFeatureBriefcasesEnabled} eq ""); $config{zimbraFeatureTasksEnabled} = "Disabled" if ($config{zimbraFeatureTasksEnabled} eq ""); } else { $config{zimbraFeatureBriefcasesEnabled} = "Enabled" if ($config{zimbraFeatureBriefcasesEnabled} eq ""); $config{zimbraFeatureTasksEnabled} = "Enabled" if ($config{zimbraFeatureTasksEnabled} eq ""); } } if (isEnabled("zimbra-imapd")) { progress "setting defaults for zimbra-imapd.\n" if $options{d}; $config{DOADDUPSTREAMIMAP} = "no"; } $config{zimbra_require_interprocess_security} = 1; $config{ZIMBRA_REQ_SECURITY}="yes"; if (isEnabled("zimbra-ldap")) { progress "setting defaults for zimbra-ldap.\n" if $options{d}; $config{DOCREATEDOMAIN} = "yes" if $newinstall; $config{LDAPROOTPASS} = genRandomPass(); $config{LDAPADMINPASS} = $config{LDAPROOTPASS}; $config{LDAPREPPASS} = $config{LDAPADMINPASS}; $config{LDAPPOSTPASS} = $config{LDAPADMINPASS}; $config{LDAPAMAVISPASS} = $config{LDAPADMINPASS}; $config{ldap_nginx_password} = $config{LDAPADMINPASS}; $config{ldap_bes_searcher_password} = $config{LDAPADMINPASS}; $config{LDAPREPLICATIONTYPE} = "master"; # Values can be master, mmr, replica $config{USEEPHEMERALSTORE} = "no"; $config{LDAPSERVERID} = 2; # Aleady enabled master should be 1, so default to next ID. $ldapRepChanged = 1; $ldapPostChanged = 1; $ldapAmavisChanged = 1; $ldapNginxChanged = 1; if ($newinstall) { $ldapBesSearcherChanged = 1; } } if(isInstalled("zimbra-proxy") && !isEnabled("zimbra-ldap")) { $config{ldap_nginx_password} = genRandomPass(); $ldapNginxChanged = 1; } $config{CREATEADMIN} = "admin\@$config{CREATEDOMAIN}"; if (isEnabled("zimbra-store")) { $config{VERSIONUPDATECHECKS} = "TRUE"; $config{zimbraVersionCheckSendNotifications} = "TRUE" if ($config{zimbraVersionCheckSendNotifications} eq ""); $config{zimbraVersionCheckNotificationEmail} = $config{CREATEADMIN} if ($config{zimbraVersionCheckNotificationEmail} eq ""); $config{zimbraVersionCheckNotificationEmailFrom} = $config{CREATEADMIN} if ($config{zimbraVersionCheckNotificationEmailFrom} eq ""); } my $tzname=qx(/bin/date '+%Z'); chomp($tzname); detail("Local timezone detected as $tzname\n"); my $tzdata = Zimbra::Util::Timezone->parse; my $tz = $tzdata->gettzbyname($tzname); $config{zimbraPrefTimeZoneId} = $tz->tzid if (defined $tz); $config{zimbraPrefTimeZoneId} = 'America/Los_Angeles' if ($config{zimbraPrefTimeZoneId} eq ""); detail("Default Olson timezone name $config{zimbraPrefTimeZoneId}\n"); #progress("tzname=$tzname tzid=$config{zimbraPrefTimeZoneId}"); $config{zimbra_ldap_userdn} = "uid=zimbra,cn=admins,$config{ldap_dit_base_dn_config}"; $config{SMTPSOURCE} = $config{CREATEADMIN}; $config{SMTPDEST} = $config{CREATEADMIN}; $config{AVUSER} = $config{CREATEADMIN}; $config{AVDOMAIN} = $config{CREATEDOMAIN}; $config{SNMPNOTIFY} = "yes"; $config{SMTPNOTIFY} = "yes"; $config{STARTSERVERS} = "yes"; if (isEnabled("zimbra-store") && isNetwork()) { $config{zimbraBackupReportEmailRecipients} = $config{CREATEADMIN}; $config{zimbraBackupReportEmailSender} = $config{CREATEADMIN}; } if (isEnabled("zimbra-mta")) { progress "setting defaults for zimbra-mta.\n" if $options{d}; my @tmpval = (qx(/opt/zimbra/libexec/zmserverips -n)); chomp(@tmpval); if (@tmpval) { $config{zimbraMtaMyNetworks} = "@tmpval"; } else { $config{zimbraMtaMyNetworks} = "127.0.0.0/8 [::1]/128 @interfaces"; } $config{postfix_mail_owner} = "postfix"; $config{postfix_setgid_group} = "postdrop"; } $config{MODE} = "https"; $config{PROXYMODE} = "https"; $config{SYSTEMMEMORY} = getSystemMemory(); $config{MYSQLMEMORYPERCENT} = mysqlMemoryPercent($config{SYSTEMMEMORY}); $config{MAILBOXDMEMORY} = mailboxdMemoryMB($config{SYSTEMMEMORY}); $config{CREATEADMINPASS} = "" unless ($config{CREATEADMINPASS}); if (!$options{c} && $newinstall) { progress "no config file and newinstall checking dns resolution\n" if $options{d}; if (lookupHostName ($config{HOSTNAME}, 'A')) { if (lookupHostName ($config{HOSTNAME}, 'AAAA')) { progress("\n\nDNS ERROR resolving $config{HOSTNAME}\n"); progress("It is suggested that the hostname be resolvable via DNS\n"); if (askYN("Change hostname","Yes") eq "yes") { setHostName(); } } } my $good = 0; if ($config{DOCREATEDOMAIN} eq "yes") { my $ans = getDnsRecords($config{CREATEDOMAIN}, 'MX'); if (!defined($ans)) { progress("\n\nDNS ERROR resolving MX for $config{CREATEDOMAIN}\n"); progress("It is suggested that the domain name have an MX record configured in DNS\n"); if (askYN("Change domain name?","Yes") eq "yes") { setCreateDomain(); } } elsif (isEnabled("zimbra-mta")) { my @answer = $ans->answer; foreach my $a (@answer) { if ($a->type eq "MX") { my $h = getDnsRecords ($a->exchange,'A'); my $ipv6 = 0; if (!defined $h) { $h = getDnsRecords ($a->exchange, 'AAAA'); $ipv6 = 1; } if (defined $h) { my @ha = $h->answer; foreach $h (@ha) { if ($ipv6) { if ($h->type eq 'AAAA') { progress "\tMX: ".$a->exchange." (".$h->address.")\n"; } } else { if ($h->type eq 'A') { progress "\tMX: ".$a->exchange." (".$h->address.")\n"; } } } } else { progress "\n\nDNS ERROR - No A or AAAA record for $config{CREATEDOMAIN}.\n"; } } } progress "\n"; foreach my $i (@interfaces) { progress "\tInterface: $i\n"; } foreach my $a (@answer) { foreach my $i (@interfaces) { if ($a->type eq "MX") { my $h = getDnsRecords ($a->exchange,'A'); if (!defined $h) { $h = getDnsRecords ($a->exchange, 'AAAA'); } if (defined $h) { my @ha = $h->answer; foreach $h (@ha) { my $interIp = NetAddr::IP->new("$i"); my $interface= lc($interIp->addr); if ($h->type eq 'A' || $h->type eq 'AAAA') { print "\t\t".$h->address."\n"; if ($h->address eq $interface) { $good = 1; last; } } } if ($good) { last; } } } } if ($good) {last;} } if (!$good) { progress ("\n\nDNS ERROR - none of the MX records for $config{CREATEDOMAIN}\n"); progress ("resolve to this host\n"); if (askYN("Change domain name?","Yes") eq "yes") { setCreateDomain(); } } } } } if (isInstalled("zimbra-proxy")) { progress "setting defaults for zimbra-proxy.\n" if $options{d}; $config{STRICTSERVERNAMEENABLED} = "TRUE"; $config{IMAPPROXYPORT} = 143; $config{IMAPSSLPROXYPORT} = 993; $config{POPPROXYPORT} = 110; $config{POPSSLPROXYPORT} = 995; $config{IMAPPORT} = 7143; $config{IMAPSSLPORT} = 7993; $config{POPPORT} = 7110; $config{POPSSLPORT} = 7995; $config{MAILPROXY} = "TRUE"; $config{HTTPPROXY} = "TRUE"; $config{HTTPPROXYPORT} = 8080; $config{HTTPSPROXYPORT} = 8443; $config{HTTPPORT} = 80; $config{HTTPSPORT} = 443; } else { $config{IMAPPROXYPORT} = 7143; $config{IMAPSSLPROXYPORT} = 7993; $config{POPPROXYPORT} = 7110; $config{POPSSLPROXYPORT} = 7995; $config{HTTPPROXYPORT} = 8080; $config{HTTPSPROXYPORT} = 8443; } if ($options{d}) { foreach my $key (sort keys %config) { print "\tDEBUG: $key=$config{$key}\n"; } } progress ( "done.\n" ); } sub getInstallStatus { progress "getting install status..." if $options{d}; if (open H, "/opt/zimbra/.install_history") { my @history = ; close H; foreach my $h (@history) { if ($h =~ /CONFIG SESSION COMPLETE/) { next; } if ($h =~ /CONFIG SESSION START/) { %configStatus = (); next; } if ($h =~ /INSTALL SESSION COMPLETE/) { next; } if ($h =~ /INSTALL SESSION START/) { %installStatus = (); %configStatus = (); next; } my ($d, $op, $stage) = split ' ', $h; if ($op eq "INSTALLED" || $op eq "UPGRADED") { my $v = $stage; $stage =~ s/[-_]\d.*//; $installStatus{$stage}{op} = $op; $installStatus{$stage}{date} = $d; if ($stage eq "zimbra-core") { $v =~ s/_HEAD.*//; $v =~ s/^zimbra-core[-_]//; if ($v =~ /\.deb$/) { my $orig_v=$v; $v =~ s/^(\d+\.\d+\.\d+\.\w+\.\w+)\..*/\1/; $v = reverse($v); $v =~ s/\./_/; $v =~ s/\./_/; $v = reverse($v); if ($v =~ /\_deb$/) { $v = $orig_v; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; } } else { $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/\1/; } $curVersion = $v; } } elsif ($op eq "CONFIGURED") { $configStatus{$stage} = $op; if ($stage =~ /Migrated/ || $stage =~ /Upgraded/) { $migratedStatus{$stage} = $op; } if ($stage eq "END") { $prevVersion = $curVersion; } } } if( !exists $installStatus{"zimbra-core"} ) { progress ("\nERROR:\n"); progress ("zimbra-core does not seem to be installed.\n"); progress ("Please install required components first. Exiting.\n\n"); exit (1); } if ( ($installStatus{"zimbra-core"}{op} eq "INSTALLED") && ($configStatus{"END"} ne "CONFIGURED") ){ $newinstall = 1; } else { $newinstall = 0; #$config{DOCREATEDOMAIN} = "no"; #$config{DOCREATEADMIN} = "no"; #setDefaultsFromLocalConfig(); } } else { $newinstall = 1; } ($prevVersionMajor,$prevVersionMinor,$prevVersionMicro,$prevVersionBuild) = $prevVersion =~ /(\d+)\.(\d+)\.(\d+_[^_]*)_(\d+)/; ($curVersionMajor,$curVersionMinor,$curVersionMicro,$curVersionBuild) = $curVersion =~ /(\d+)\.(\d+)\.(\d+_[^_]*)_(\d+)/; ($curVersionMicroMicro, $curVersionType) = $curVersionMicro =~ /(\d+)_(.*)/; if ($options{d}) { progress "done.\n"; progress "Previous version maj:$prevVersionMajor minor:$prevVersionMinor micro:$prevVersionMicro build:$prevVersionBuild\n"; progress "Current version maj:$curVersionMajor minor:$curVersionMinor micro:$curVersionMicro build:$curVersionBuild\n"; } } sub setDefaultsFromLocalConfig { progress ("Setting defaults from existing config..."); $config{HOSTNAME} = getLocalConfig ("zimbra_server_hostname"); $config{HOSTNAME} = lc ($config{HOSTNAME}); my $ldapUrl = getLocalConfig ("ldap_master_url"); my $ld = (split ' ', $ldapUrl)[0]; my $p = $ld; $p =~ s/ldaps?:\/\///; $p =~ s/.*:?//; if ($p ne "") { $config{LDAPPORT} = $p; } else { $p = getLocalConfig ("ldap_port"); if ($p ne "") { $config{LDAPPORT} = $p; } } my $h = $ld; chomp($h); $h =~ s/"//g; $h =~ s/ldaps?:\/\///g; $h =~ s/:\d+//g; if ($h ne "") { $config{LDAPHOST} = $h; } else { $h = getLocalConfig ("ldap_host"); if ($h ne "") { $config{LDAPHOST} = $h; } } $config{ldap_url} = getLocalConfig("ldap_url"); $config{LDAPROOTPASS} = getLocalConfig ("ldap_root_password"); $config{LDAPADMINPASS} = getLocalConfig ("zimbra_ldap_password"); $config{SQLROOTPASS} = getLocalConfig ("mysql_root_password"); $config{ZIMBRASQLPASS} = getLocalConfig ("zimbra_mysql_password"); $config{MAILBOXDMEMORY} = getLocalConfig ("mailboxd_java_heap_size"); $config{mailboxd_directory} = getLocalConfig("mailboxd_directory"); $config{mailboxd_keystore} = getLocalConfig("mailboxd_keystore"); $config{mailboxd_keystore_password} = getLocalConfig ("mailboxd_keystore_password") if (getLocalConfig("mailboxd_keystore_password") ne ""); $config{mailboxd_truststore_password} = getLocalConfig ("mailboxd_truststore_password") if (getLocalConfig("mailboxd_truststore_password") ne ""); $config{zimbra_ldap_userdn} = getLocalConfig("zimbra_ldap_userdn") if (getLocalConfig("zimbra_ldap_userdn") ne ""); $config{zimbra_require_interprocess_security} = getLocalConfig("zimbra_require_interprocess_security"); if ($config{zimbra_require_interprocess_security}) { $config{ZIMBRA_REQ_SECURITY} = "yes"; } else { $config{ZIMBRA_REQ_SECURITY} = "no"; } $config{ldap_dit_base_dn_config} = getLocalConfig("ldap_dit_base_dn_config"); $config{ldap_dit_base_dn_config} = "cn=zimbra" if ($config{ldap_dit_base_dn_config} eq ""); if (isEnabled("zimbra-snmp")) { $config{SNMPNOTIFY} = getLocalConfig("snmp_notify"); $config{SNMPNOTIFY} = "yes" if ($config{SNMPNOTIFY} eq ""); $config{SMTPNOTIFY} = getLocalConfig("smtp_notify"); $config{SMTPNOTIFY} = "yes" if ($config{SMTPNOTIFY} eq ""); $config{SNMPTRAPHOST} = getLocalConfig("snmp_trap_host"); $config{SNMPTRAPHOST} = $config{HOSTNAME} if ($config{SNMPTRAPHOST} eq ""); } $config{SMTPSOURCE} = getLocalConfig("smtp_source"); $config{SMTPSOURCE} = $config{CREATEADMIN} if ($config{SMTPSOURCE} eq ""); $config{SMTPDEST} = getLocalConfig("smtp_destination"); $config{SMTPDEST} = $config{CREATEADMIN} if ($config{SMTPDEST} eq ""); $config{AVUSER} = getLocalConfig("av_notify_user"); $config{AVUSER} = $config{CREATEADMIN} if ($config{AVUSER} eq ""); $config{AVDOMAIN} = getLocalConfig("av_notify_domain"); $config{AVDOMAIN} = $config{CREATEDOMAIN} if ($config{AVDOMAIN} eq ""); if (isEnabled("zimbra-mta")) { $config{postfix_mail_owner} = getLocalConfig ("postfix_mail_owner"); if ($config{postfix_mail_owner} eq "") { $config{postfix_mail_owner} = "postfix"; } $config{postfix_setgid_group} = getLocalConfig ("postfix_setgid_group"); if ($config{postfix_setgid_group} eq "") { $config{postfix_setgid_group} = "postdrop"; } } if (isEnabled("zimbra-ldap")) { $config{LDAPREPPASS} = getLocalConfig ("ldap_replication_password"); if ($config{LDAPREPPASS} eq "") { $config{LDAPREPPASS} = $config{LDAPADMINPASS}; $ldapRepChanged = 1; } } if (isEnabled("zimbra-ldap")) { if (isLdapMaster()) { $config{ldap_bes_searcher_password} = getLocalConfig ("ldap_bes_searcher_password"); if ($config{ldap_bes_searcher_password} eq "") { $config{ldap_bes_searcher_password} = $config{LDAPADMINPASS}; $ldapBesSearcherChanged = 1; } } } if (isEnabled("zimbra-ldap") || isEnabled("zimbra-mta")) { $config{LDAPPOSTPASS} = getLocalConfig ("ldap_postfix_password"); if ($config{LDAPPOSTPASS} eq "") { $config{LDAPPOSTPASS} = $config{LDAPADMINPASS}; $ldapPostChanged = 1; } $config{LDAPAMAVISPASS} = getLocalConfig ("ldap_amavis_password"); if ($config{LDAPAMAVISPASS} eq "") { $config{LDAPAMAVISPASS} = $config{LDAPADMINPASS}; $ldapAmavisChanged = 1; } } if (isEnabled("zimbra-ldap") || isEnabled("zimbra-proxy")) { $config{ldap_nginx_password} = getLocalConfig ("ldap_nginx_password"); if ($config{ldap_nginx_password} eq "") { $config{ldap_nginx_password} = $config{LDAPADMINPASS}; $ldapNginxChanged = 1; } } if ($options{d}) { foreach my $key (sort keys %config) { print "\tlc DEBUG: $key=$config{$key}\n"; } } progress("done.\n"); } sub ask { my $prompt = shift; my $default = shift; if ($default eq "") { print "$prompt "; } else { print "$prompt [$default] "; } my $rc = <>; chomp $rc; if ($rc eq "") {return $default;} return $rc; } sub askPassword { my $prompt = shift; my $default = shift; while (1) { my $v = ask($prompt, $default); # although they are valid pass characters avoid $ and | # here because they cause quoting problems. if ($v =~ /\$|\\/g) { print "Invalid metacharater used.\n"; next; } if ($v ne "") {return $v;} print "A non-blank answer is required\n"; } } sub askYN { my $prompt = shift; my $default = shift; while (1) { my $v = ask($prompt, $default); $v = lc($v); $v = substr ($v,0,1); if ($v eq "y") {return "yes";} if ($v eq "n") {return "no";} print "A Yes/No answer is required\n"; } } sub askTF { my $prompt = shift; my $default = shift; while (1) { my $v = ask($prompt, $default); $v = lc($v); $v = substr ($v,0,1); if ($v eq "t") {return "TRUE";} if ($v eq "f") {return "FALSE";} print "A True/False answer is required\n"; } } sub askNum { my $prompt = shift; my $default = shift; while (1) { my $v = ask($prompt, $default); my $i = int($v); if ($v eq $i) { return $v; } print "A numeric response is required!\n"; } } sub askPositiveInt { my $prompt = shift; my $default = shift; while (1) { my $v = ask($prompt, $default); my $i = int($v); if ($v eq $i && $v > 0) { return $v; } print "A positive integer response is required!\n"; } } sub askNonBlank { my $prompt = shift; my $default = shift; while (1) { my $v = ask($prompt, $default); if ($v ne "") {return $v;} print "A non-blank answer is required\n"; } } sub askFileName { my $prompt = shift; my $default = shift; while (1) { my $v = ask($prompt, $default); if ($v ne "" && -f $v) {return $v;} print "A non-blank answer is required\n" if ($v eq ""); print "$v must exist and be readable\n" if (!-f $v && $v ne ""); } } sub setEphemeralBackendURL { my $rc = 1; while ($rc != 0) { my $newURL = ask("Value for zimbraEphemeralBackendURL:", $config{EphemeralBackendURL}); $rc = runAsZimbra("zmjava com.zimbra.cs.ephemeral.EphemeralStore -u $newURL"); if ($rc == 0) { $config{EphemeralBackendURL} = $newURL; last; } progress("\nUnable to access the Ephemeral Store provider using $newURL\n"); progress("The Ephemeral Store provider must be active\n"); if (askYN("Revert to storing ephemeral attributes in Ldap?","No") eq "yes") { $config{USEEPHEMERALSTORE} = "no"; delete($config{EphemeralBackendURL}) if (exists($config{EphemeralBackendURL})); last; } } } sub setCreateDomain { my $oldDomain = $config{CREATEDOMAIN}; my $good = 0; while (1) { $config{CREATEDOMAIN} = ask("Create domain:", $config{CREATEDOMAIN}); my $ans = getDnsRecords($config{CREATEDOMAIN}, 'MX'); if (!defined ($ans)) { progress("\n\nDNS ERROR resolving MX for $config{CREATEDOMAIN}\n"); progress("It is suggested that the domain name have an MX record configured in DNS\n"); if (askYN("Re-Enter domain name?","Yes") eq "no") { last; } $config{CREATEDOMAIN} = $oldDomain; next; } elsif (isEnabled("zimbra-mta")) { my @answer = $ans->answer; foreach my $a (@answer) { if ($a->type eq "MX") { my $h = getDnsRecords ($a->exchange,'A'); my $ipv6 = 0; if (!defined $h) { $h = getDnsRecords ($a->exchange, 'AAAA'); $ipv6 = 1; } if (defined $h) { my @ha = $h->answer; foreach $h (@ha) { if ($ipv6) { if ($h->type eq 'AAAA') { progress "\tMX: ".$a->exchange." (".$h->address.")\n"; } } else { if ($h->type eq 'A') { progress "\tMX: ".$a->exchange." (".$h->address.")\n"; } } } } else { progress "\n\nDNS ERROR - No A or AAAA record for $config{CREATEDOMAIN}.\n"; } } } progress "\n"; foreach my $i (@interfaces) { progress "\tInterface: $i\n"; } foreach my $a (@answer) { foreach my $i (@interfaces) { if ($a->type eq "MX") { my $h = getDnsRecords ($a->exchange,'A'); if (!defined $h) { $h = getDnsRecords ($a->exchange, 'AAAA'); } if (defined $h) { my @ha = $h->answer; foreach $h (@ha) { my $interIp = NetAddr::IP->new("$i"); my $interface= lc($interIp->addr); if ($h->type eq 'A' || $h->type eq 'AAAA') { if ($h->address eq $interface) { $good = 1; last; } } } } if ($good) { last; } } } if ($good) { last; } } if ($good) { last; } else { progress ("\n\nDNS ERROR - none of the MX records for $config{CREATEDOMAIN}\n"); progress ("resolve to this host\n"); progress ("It is suggested that the MX record resolve to this host\n"); if (askYN("Re-Enter domain name?","Yes") eq "no") { last; } $config{CREATEDOMAIN} = $oldDomain; next; } } last; } my ($u,$d) = split ('@', $config{CREATEADMIN}); my $old = $config{CREATEADMIN}; $config{CREATEADMIN} = $u.'@'.$config{CREATEDOMAIN}; $config{AVUSER} = $config{CREATEADMIN} if ($old eq $config{AVUSER}); $config{AVDOMAIN} = $config{CREATEDOMAIN} if ($config{AVDOMAIN} eq $oldDomain); if ($old eq $config{SMTPDEST}) { $config{SMTPDEST} = $config{CREATEADMIN}; } if ($old eq $config{SMTPSOURCE}) { $config{SMTPSOURCE} = $config{CREATEADMIN}; } my ($spamUser, $spamDomain) = split ('@', $config{TRAINSASPAM}); $config{TRAINSASPAM} = $spamUser.'@'.$config{CREATEDOMAIN} if ($spamDomain eq $oldDomain); my ($hamUser, $hamDomain) = split ('@', $config{TRAINSAHAM}); $config{TRAINSAHAM} = $hamUser.'@'.$config{CREATEDOMAIN} if ($hamDomain eq $oldDomain); my ($virusUser, $virusDomain) = split ('@', $config{VIRUSQUARANTINE}); $config{VIRUSQUARANTINE} = $virusUser.'@'.$config{CREATEDOMAIN} if ($virusDomain eq $oldDomain); my ($vcFromUser, $vcFromDomain) = split ('@', $config{zimbraVersionCheckNotificationEmailFrom}); $config{zimbraVersionCheckNotificationEmailFrom} = $vcFromUser.'@'.$config{CREATEDOMAIN} if ($vcFromDomain eq $oldDomain); my ($vcUser, $vcDomain) = split ('@', $config{zimbraVersionCheckNotificationEmail}); $config{zimbraVersionCheckNotificationEmail} = $vcUser.'@'.$config{CREATEDOMAIN} if ($vcDomain eq $oldDomain); } sub setLdapBaseDN { while (1) { print "Warning: Do not change this from the default value unless\n"; print "you are absolutely sure you know what you are doing!\n\n"; my $new = askNonBlank("Ldap base DN:", $config{ldap_dit_base_dn_config}); if ($config{ldap_dit_base_dn_config} ne $new) { $config{ldap_dit_base_dn_config} = $new; } return; } } sub setNotebookAccount { while (1) { my $new = ask("Global Documents account:", $config{NOTEBOOKACCOUNT}); my ($u,$d) = split ('@', $new); my ($adminUser,$adminDomain) = split('@', $config{CREATEADMIN}); if ($d ne $config{CREATEDOMAIN} && $d ne $adminDomain) { if ($config{CREATEDOMAIN} eq $adminDomain) { progress ( "You must create the user under the domain $config{CREATEDOMAIN}\n" ); } else { progress ( "You must create the user under the domain $config{CREATEDOMAIN} or $adminDomain\n" ); } } else { $config{NOTEBOOKACCOUNT} = $new; last; } } } sub setTrainSASpam { while (1) { my $new = ask("Spam training user:", $config{TRAINSASPAM}); my ($u,$d) = split ('@', $new); my ($adminUser,$adminDomain) = split('@', $config{CREATEADMIN}); if ($d ne $config{CREATEDOMAIN} && $d ne $adminDomain) { if ($config{CREATEDOMAIN} eq $adminDomain) { progress ( "You must create the user under the domain $config{CREATEDOMAIN}\n" ); } else { progress ( "You must create the user under the domain $config{CREATEDOMAIN} or $adminDomain\n" ); } } else { $config{TRAINSASPAM} = $new; last; } } } sub setTrainSAHam { while (1) { my $new = ask("Ham training user:", $config{TRAINSAHAM}); my ($u,$d) = split ('@', $new); my ($adminUser,$adminDomain) = split('@', $config{CREATEADMIN}); if ($d ne $config{CREATEDOMAIN} && $d ne $adminDomain) { if ($config{CREATEDOMAIN} eq $adminDomain) { progress ( "You must create the user under the domain $config{CREATEDOMAIN}\n" ); } else { progress ( "You must create the user under the domain $config{CREATEDOMAIN} or $adminDomain\n" ); } } else { $config{TRAINSAHAM} = $new; last; } } } sub setAmavisVirusQuarantine{ while (1) { my $new = ask("Anti-virus quarantine user:", $config{VIRUSQUARANTINE}); my ($u,$d) = split ('@', $new); my ($adminUser,$adminDomain) = split('@', $config{CREATEADMIN}); if ($d ne $config{CREATEDOMAIN} && $d ne $adminDomain) { if ($config{CREATEDOMAIN} eq $adminDomain) { progress ( "You must create the user under the domain $config{CREATEDOMAIN}\n" ); } else { progress ( "You must create the user under the domain $config{CREATEDOMAIN} or $adminDomain\n" ); } } else { $config{VIRUSQUARANTINE} = $new; last; } } } sub setVersionCheckNotificationEmail { while (1) { my $new = ask("Version update destination address:", $config{zimbraVersionCheckNotificationEmail}); unless(validEmailAddress($new)) { progress ( "Must enter a valid email address.\n"); next; } $config{zimbraVersionCheckNotificationEmail} = $new; last; } } sub setVersionCheckNotificationEmailFrom { while (1) { my $new = ask("Version update source address:", $config{zimbraVersionCheckNotificationEmailFrom}); unless(validEmailAddress($new)) { progress ( "Must enter a valid email address.\n"); next; } $config{zimbraVersionCheckNotificationEmailFrom} = $new; last; } } sub setMasterDNSIP { while (1) { my $new = ask("IP Address(es) of Master DNS Server(s), space separated:", $config{zimbraDNSMasterIP}); my @IPs = split (' ', $new); unless(!validIPAddress(@IPs)) { progress("Supplied IP address(es) must be valid\n"); next; } $config{zimbraDNSMasterIP} = $new; last; } } sub setCreateAdmin { while (1) { my $new = ask("Create admin user:", $config{CREATEADMIN}); my ($u,$d) = split ('@', $new); unless(validEmailAddress($new)) { progress ( "Admin user must be a valid email account [$u\@$config{CREATEDOMAIN}]\n"); next; } # spam/ham/quanrantine accounts follow admin domain if ldap isn't install # this prevents us from trying to provision in a non-existent domain if (!isEnabled("zimbra-ldap")) { my ($spamUser, $spamDomain) = split ('@', $config{TRAINSASPAM}); my ($hamUser, $hamDomain) = split ('@', $config{TRAINSAHAM}); my ($virusUser, $virusDomain) = split ('@', $config{VIRUSQUARANTINE}); $config{CREATEDOMAIN} = $d if ($config{CREATEDOMAIN} ne $d); $config{TRAINSASPAM} = $spamUser.'@'.$d if ($spamDomain ne $d); $config{TRAINSAHAM} = $hamUser.'@'.$d if ($hamDomain ne $d); $config{VIRUSQUARANTINE} = $virusUser.'@'.$d if ($virusDomain ne $d); $config{AVDOMAIN} = $d if ($config{AVDOMAIN} ne $d); } $config{zimbraBackupReportEmailRecipients} = $new if ($config{zimbraBackupReportEmailRecipients} eq $config{CREATEADMIN}); $config{zimbraBackupReportEmailSender} = $new if ($config{zimbraBackupReportEmailSender} eq $config{CREATEADMIN}); if ($config{CREATEADMIN} eq $config{AVUSER}) { $config{AVUSER} = $new; } if ($config{CREATEADMIN} eq $config{SMTPDEST}) { $config{SMTPDEST} = $new; } if ($config{CREATEADMIN} eq $config{SMTPSOURCE}) { $config{SMTPSOURCE} = $new; } $config{CREATEADMIN} = $new; last; } setAdminPass(); } sub removeUnusedWebapps { my $webAppsDir = "/opt/zimbra/jetty/webapps"; if ($config{SERVICEWEBAPP} eq "no") { system("rm -rf $webAppsDir/service") if (-d "$webAppsDir/service"); } if ($config{UIWEBAPPS} eq "no") { system("rm -rf $webAppsDir/zimbra") if (-d "$webAppsDir/zimbra"); system("rm -rf $webAppsDir/zimbraAdmin") if (-d "$webAppsDir/zimbraAdmin"); } defineInstallWebapps(); getInstalledWebapps(); } sub validEmailAddress { return($_[0] =~ m/^[^@]+@([-\w]+\.)+[A-Za-z]{2,4}/ ? 1 : 0); } sub validIPAddress { my $rc = 0; foreach my $ip (@_) { chomp($ip); my $testip = NetAddr::IP->new($ip); if (ref($testip) ne 'NetAddr::IP') { $rc = 1; } } return $rc; } sub setLdapRootPass { while (1) { my $new = askPassword("Password for ldap root user (min 6 characters):", $config{LDAPROOTPASS}); if (length($new) >= 6) { if ($config{LDAPROOTPASS} ne $new) { $config{LDAPROOTPASS} = $new; $ldapRootPassChanged = 1; } return; } else { print "Minimum length of 6 characters!\n"; } } } sub setLdapAdminPass { while (1) { my $new = askPassword("Password for ldap admin user (min 6 characters):", $config{LDAPADMINPASS}); if (length($new) >= 6) { if ($config{LDAPADMINPASS} ne $new) { $config{LDAPADMINPASS} = $new; $ldapAdminPassChanged = 1; } ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST}); return; } else { print "Minimum length of 6 characters!\n"; } } } sub setLdapRepPass { while (1) { my $new = askPassword("Password for ldap replication user (min 6 characters):", $config{LDAPREPPASS}); if (length($new) >= 6) { if ($config{LDAPREPPASS} ne $new) { $config{LDAPREPPASS} = $new; $ldapRepChanged = 1; } ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST}); return; } else { print "Minimum length of 6 characters!\n"; } } } sub setLdapBesSearchPass { while (1) { my $new = askPassword("Password for ldap BES user (min 6 characters):", $config{ldap_bes_searcher_password}); if (length($new) >= 6) { if ($config{ldap_bes_searcher_password} ne $new) { $config{ldap_bes_searcher_password} = $new; $ldapBesSearcherChanged = 1; } ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST}); return; } else { print "Minimum length of 6 characters!\n"; } } } sub setLdapPostPass { while (1) { my $new = askPassword("Password for ldap Postfix user (min 6 characters):", $config{LDAPPOSTPASS}); if (length($new) >= 6) { if ($config{LDAPPOSTPASS} ne $new) { $config{LDAPPOSTPASS} = $new; $ldapPostChanged = 1; } ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST}); return; } else { print "Minimum length of 6 characters!\n"; } } } sub setLdapAmavisPass { while (1) { my $new = askPassword("Password for ldap Amavis user (min 6 characters):", $config{LDAPAMAVISPASS}); if (length($new) >= 6) { if ($config{LDAPAMAVISPASS} ne $new) { $config{LDAPAMAVISPASS} = $new; $ldapAmavisChanged = 1; } ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST}); return; } else { print "Minimum length of 6 characters!\n"; } } } sub setLdapNginxPass { while (1) { my $new = askPassword("Password for ldap Nginx user (min 6 characters):", $config{ldap_nginx_password}); if (length($new) >= 6) { if ($config{ldap_nginx_password} ne $new) { $config{ldap_nginx_password} = $new; $ldapNginxChanged = 1; } ldapIsAvailable() if ($config{HOSTNAME} ne $config{LDAPHOST}); return; } else { print "Minimum length of 6 characters!\n"; } } } sub setAdminPass { if ($config{CREATEADMIN} ne "") { while (1) { if ($config{CREATEADMINPASS} eq "") { $config{CREATEADMINPASS} = genRandomPass(); } my $new = askPassword("Password for $config{CREATEADMIN} (min 6 characters):", $config{CREATEADMINPASS}); if (length($new) >= 6) { $config{CREATEADMINPASS} = $new; return; } else { print "Minimum length of 6 characters!\n"; } } } } sub setLicenseKey { while (1) { my $new = askNonBlank("Please enter the license key (enter 'r' for previous menu):",$config{LICENSEKEY}); if ($new eq "r") { chooseLicenseActivationOption(); return; } if ((length($new) >= 18 && length($new) <= 24) && $new =~ /^[A-Za-z0-9]+$/) { $config{LICENSEKEY} = $new; return; } else { print "Invalid license key entered. The license key should be an alphanumeric string of 18-24 characters without any special characters!\n"; } } } sub chooseLicenseActivationOption { while (1) { print "1) Activate license with installation\n"; print "2) Activate license after installation\n\n"; my $choice = askNonBlank("Select, or 'r' for previous menu","r"); if ($choice eq "1") { setLicenseKey(); if ($config{LICENSEKEY} ne "") { system("echo \"$config{LICENSEKEY}\" > $license_file"); system("chown zimbra:zimbra $license_file"); system("chmod 644 $license_file"); $config{LICENSEACTIVATIONOPTION} = $choice; } return; } if ($choice eq "2") { system("rm -rf $license_file") if -e $license_file; $config{LICENSEACTIVATIONOPTION} = $choice; print "After the successful installation, use zmlicense -a to activate license key or contact support team for an offline activation file \n"; return; } if ($choice eq "r") { return; } print "Please enter a valid option!\n\n"; } } sub setSmtpSource { $config{SMTPSOURCE} = askNonBlank("SMTP Source address:", $config{SMTPSOURCE}); } sub setSmtpDest { $config{SMTPDEST} = askNonBlank("SMTP Destination address:", $config{SMTPDEST}); } sub setSnmpTrapHost { $config{SNMPTRAPHOST} = askNonBlank("SNMP Trap host:", $config{SNMPTRAPHOST}); } sub setOnlyOfficeHost { $config{ONLYOFFICEHOSTNAME} = askNonBlank("Onlyoffice server:", $config{ONLYOFFICEHOSTNAME}); } sub setAvUser { $config{AVUSER} = askNonBlank("Notification address for AV alerts:", $config{AVUSER}); (undef, $config{AVDOMAIN}) = (split ('@',$config{AVUSER}))[1]; } sub toggleYN { my $key = shift; $config{$key} = ($config{$key} eq "yes")?"no":"yes"; } sub toggleTF { my $key = shift; $config{$key} = ($config{$key} eq "TRUE")?"FALSE":"TRUE"; if ($key eq "MAILPROXY") { &toggleMailProxy(); } if ($key eq "HTTPPROXY") { &toggleWebProxy(); } } sub toggleSERVICEWEBAPP { my $key = shift; $config{SERVICEWEBAPP} = ($config{SERVICEWEBAPP} eq "yes")?"no":"yes"; } sub toggleConfigEnabled { my $key = shift; $config{$key} = ($config{$key} eq "Enabled")?"Disabled":"Enabled"; } sub toggleMailProxy() { if ($config{MAILPROXY} eq "TRUE") { $config{IMAPPORT} = 7143; $config{IMAPSSLPORT} = 7993; $config{POPPORT} = 7110; $config{POPSSLPORT} = 7995; $config{IMAPPROXYPORT} = 143; $config{IMAPSSLPROXYPORT} = 993; $config{POPPROXYPORT} = 110; $config{POPSSLPROXYPORT} = 995; } else { $config{IMAPPORT} = 143; $config{IMAPSSLPORT} = 993; $config{POPPORT} = 110; $config{POPSSLPORT} = 995; $config{IMAPPROXYPORT} = 7143; $config{IMAPSSLPROXYPORT} = 7993; $config{POPPROXYPORT} = 7110; $config{POPSSLPROXYPORT} = 7995; } } sub toggleWebProxy() { if ($config{HTTPPROXY} eq "TRUE") { $config{HTTPPORT} = 8080; $config{HTTPSPORT} = 8443; $config{HTTPPROXYPORT} = 80; $config{HTTPSPROXYPORT} = 443; } else { $config{HTTPPORT} = 80; $config{HTTPSPORT} = 443; $config{HTTPPROXYPORT} = 8080; $config{HTTPSPROXYPORT} = 8443; } } sub setUseProxy { if (isEnabled("zimbra-proxy")) { if ($config{MAILPROXY} eq "TRUE") { if ($config{IMAPPROXYPORT} == $config{IMAPPORT}) { $config{IMAPPORT} = 7000+$config{IMAPPROXYPORT}; } if ($config{IMAPPORT}+7000 == $config{IMAPPROXYPORT}) { $config{IMAPPORT} = $config{IMAPPROXYPORT}; $config{IMAPPROXYPORT} = $config{IMAPPROXYPORT}-7000; } if ($config{IMAPSSLPROXYPORT} == $config{IMAPSSLPORT}) { $config{IMAPSSLPORT} = 7000+$config{IMAPSSLPROXYPORT}; } if ($config{IMAPSSLPORT}+7000 == $config{IMAPSSLPROXYPORT}) { $config{IMAPSSLPORT} = $config{IMAPSSLPROXYPORT}; $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPROXYPORT}-7000; } if ($config{POPPROXYPORT} == $config{POPPORT}) { $config{POPPORT} = 7000+$config{POPPROXYPORT}; } if ($config{POPPORT}+7000 == $config{POPPROXYPORT}) { $config{POPPORT} = $config{POPPROXYPORT}; $config{POPPROXYPORT} = $config{POPPROXYPORT}-7000; } if ($config{POPSSLPROXYPORT} == $config{POPSSLPORT}) { $config{POPSSLPORT} = 7000+$config{POPSSLPROXYPORT}; } if ($config{POPSSLPORT}+7000 == $config{POPSSLPROXYPORT}) { $config{POPSSLPORT} = $config{POPSSLPROXYPORT}; $config{POPSSLPROXYPORT} = $config{POPSSLPROXYPORT}-7000; } } else { if ($config{IMAPPROXYPORT}+7000 == $config{IMAPPORT}) { $config{IMAPPORT} = $config{IMAPPROXYPORT}; $config{IMAPPROXYPORT} = $config{IMAPPROXYPORT}+7000; } if ($config{IMAPSSLPROXYPORT}+7000 == $config{IMAPSSLPORT}) { $config{IMAPSSLPORT} = $config{IMAPSSLPROXYPORT}; $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPROXYPORT} + 7000; } if ($config{POPPROXYPORT}+7000 == $config{POPPORT}) { $config{POPPORT} = $config{POPPROXYPORT}; $config{POPPROXYPORT} = $config{POPPROXYPORT} + 7000; } if ($config{POPSSLPROXYPORT}+7000 == $config{POPSSLPORT}) { $config{POPSSLPORT} = $config{POPSSLPROXYPORT}; $config{POPSSLPROXYPORT} = $config{POPSSLPROXYPORT}+7000; } } if ($config{HTTPPROXY} eq "TRUE") { if ($config{HTTPROXYPPORT} == $config{HTTPPORT}) { $config{HTTPPORT} = 8000+$config{HTTPPROXYPORT}; } if ($config{HTTPPORT}+8000 == $config{HTTPPROXYPORT}) { $config{HTTPPORT} = $config{HTTPPROXYPORT}; $config{HTTPPROXYPORT} = $config{HTTPPORT} - 8000; } if ($config{HTTPSPROXYPORT} == $config{HTTPSPORT}) { $config{HTTPSPORT} = 8000+$config{HTTPSPROXYPORT}; } if ($config{HTTPSPORT}+8000 == $config{HTTPSPROXYPORT}) { $config{HTTPSPORT} = $config{HTTPSPROXYPORT}; $config{HTTPSPROXYPORT} = $config{HTTPSPORT} - 8000; } } else { if ($config{HTTPPROXYPORT}+8000 == $config{HTTPPORT}) { $config{HTTPPORT} = $config{HTTPPROXYPORT}; $config{HTTPPROXYPORT} = $config{HTTPPORT}+8000; } if ($config{HTTPSPROXYPORT}+8000 == $config{HTTPSPORT}) { $config{HTTPSPORT} = $config{HTTPSPROXYPORT}; $config{HTTPSPROXYPORT} = $config{HTTPSPORT}+8000; } } } else { if (!isInstalled("zimbra-store")) { if ($config{IMAPPROXYPORT}+7000 == $config{IMAPPORT}) { $config{IMAPPORT} = $config{IMAPPROXYPORT}; $config{IMAPPROXYPORT} = $config{IMAPPROXYPORT}+7000; } if ($config{IMAPSSLPROXYPORT}+7000 == $config{IMAPSSLPORT}) { $config{IMAPSSLPORT} = $config{IMAPSSLPROXYPORT}; $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPROXYPORT} + 7000; } if ($config{POPPROXYPORT}+7000 == $config{POPPORT}) { $config{POPPORT} = $config{POPPROXYPORT}; $config{POPPROXYPORT} = $config{POPPROXYPORT} + 7000; } if ($config{POPSSLPROXYPORT}+7000 == $config{POPSSLPORT}) { $config{POPSSLPORT} = $config{POPSSLPROXYPORT}; $config{POPSSLPROXYPORT} = $config{POPSSLPROXYPORT}+7000; } if ($config{HTTPPROXYPORT}+8000 == $config{HTTPPORT}) { $config{HTTPPORT} = $config{HTTPPROXYPORT}; $config{HTTPPROXYPORT} = $config{HTTPPORT}+8000; } if ($config{HTTPSPROXYPORT}+8000 == $config{HTTPSPORT}) { $config{HTTPSPORT} = $config{HTTPSPROXYPORT}; $config{HTTPSPROXYPORT} = $config{HTTPSPORT}+8000; } } else { if ($config{"zimbraMailProxy"} eq "TRUE") { if ($config{IMAPPROXYPORT} == $config{IMAPPORT}) { $config{IMAPPORT} = 7000+$config{IMAPPROXYPORT}; } if ($config{IMAPPORT}+7000 == $config{IMAPPROXYPORT}) { $config{IMAPPORT} = $config{IMAPPROXYPORT}; $config{IMAPPROXYPORT} = $config{IMAPPROXYPORT}-7000; } if ($config{IMAPSSLPROXYPORT} == $config{IMAPSSLPORT}) { $config{IMAPSSLPORT} = 7000+$config{IMAPSSLPROXYPORT}; } if ($config{IMAPSSLPORT}+7000 == $config{IMAPSSLPROXYPORT}) { $config{IMAPSSLPORT} = $config{IMAPSSLPROXYPORT}; $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPROXYPORT}-7000; } if ($config{POPPROXYPORT} == $config{POPPORT}) { $config{POPPORT} = 7000+$config{POPPROXYPORT}; } if ($config{POPPORT}+7000 == $config{POPPROXYPORT}) { $config{POPPORT} = $config{POPPROXYPORT}; $config{POPPROXYPORT} = $config{POPPROXYPORT}-7000; } if ($config{POPSSLPROXYPORT} == $config{POPSSLPORT}) { $config{POPSSLPORT} = 7000+$config{POPSSLPROXYPORT}; } if ($config{POPSSLPORT}+7000 == $config{POPSSLPROXYPORT}) { $config{POPSSLPORT} = $config{POPSSLPROXYPORT}; $config{POPSSLPROXYPORT} = $config{POPSSLPROXYPORT}-7000; } } if ($config{"zimbraWebProxy"} eq "TRUE") { if ($config{HTTPROXYPPORT} == $config{HTTPPORT}) { $config{HTTPPORT} = 8000+$config{HTTPPROXYPORT}; } if ($config{HTTPPORT}+8000 == $config{HTTPPROXYPORT}) { $config{HTTPPORT} = $config{HTTPPROXYPORT}; $config{HTTPPROXYPORT} = $config{HTTPPORT} - 8000; } if ($config{HTTPSPROXYPORT} == $config{HTTPSPORT}) { $config{HTTPSPORT} = 8000+$config{HTTPSPROXYPORT}; } if ($config{HTTPSPORT}+8000 == $config{HTTPSPROXYPORT}) { $config{HTTPSPORT} = $config{HTTPSPROXYPORT}; $config{HTTPSPROXYPORT} = $config{HTTPSPORT} - 8000; } } } } } sub setStoreMode { while (1) { my $m = askNonBlank("Please enter the web server mode (http,https,both,mixed,redirect)", $config{MODE}); if (isInstalled("zimbra-proxy")) { if ($config{zimbra_require_interprocess_security}) { if ($m eq "https" || $m eq "both" ) { $config{MODE} = $m; return; } else { print qq(Only "https" and "both" are valid modes when requiring interprocess security with web proxy.\n); } } else { if ($m eq "http" || $m eq "both" ) { $config{MODE} = $m; return; } else { print qq(Only "http" and "both" are valid modes when not requiring interprocess security with web proxy.\n); } } } else { my @proxytargets; open(ZMPROV, "$ZMPROV gas proxy 2>/dev/null|"); chomp(@proxytargets = ); close(ZMPROV); if (scalar @proxytargets) { if ($config{zimbra_require_interprocess_security}) { if ($m eq "https" || $m eq "both" ) { $config{MODE} = $m; return; } else { print qq(Only "https" and "both" are valid modes when requiring interprocess security with web proxy.\n); } } else { if ($m eq "http" || $m eq "both" ) { $config{MODE} = $m; return; } else { print qq(Only "http" and "both" are valid modes when not requiring interprocess security with web proxy.\n); } } } else { if ($m eq "http" || $m eq "https" || $m eq "mixed" || $m eq "both" || $m eq "redirect" ) { $config{MODE} = $m; return; } } } print "Please enter a valid mode!\n"; } } sub setProxyMode { while (1) { my $m = askNonBlank("Please enter the proxy server mode (http,https,both,mixed,redirect)", $config{PROXYMODE}); if ($config{zimbra_require_interprocess_security}) { if ($m eq "https" || $m eq "redirect") { $config{PROXYMODE} = $m; return; } else { print qq(Only "https" and "redirect" are valid modes when requiring interprocess security with web proxy.\n); } } else { if ($m eq "http" || $m eq "https" || $m eq "mixed" || $m eq "both" || $m eq "redirect" ) { $config{PROXYMODE} = $m; return; } } print "Please enter a valid mode!\n"; } } sub changeLdapHost { $config{LDAPHOST} = shift; $config{LDAPHOST} = lc($config{LDAPHOST}); if (isInstalled("zimbra-ldap") && $config{LDAPHOST} eq "") { $ldapReplica=0; $config{LDAPREPLICATIONTYPE}="master"; } elsif (isInstalled("zimbra-ldap") && $config{LDAPHOST} ne $config{HOSTNAME}) { $ldapReplica=1; $config{LDAPREPLICATIONTYPE}="replica"; } elsif (isInstalled("zimbra-ldap") && $config{LDAPHOST} eq $config{HOSTNAME}) { $ldapReplica=0; $config{LDAPREPLICATIONTYPE}="master"; } } sub changeLdapPort { $config{LDAPPORT} = shift; } sub changeLdapServerID { $config{LDAPSERVERID} = shift; } sub getDnsRecords { my $name = shift; my $qtype = shift; my $res = Net::DNS::Resolver->new; my @servers = $res->nameservers(); my $ans = $res->search ($name, $qtype); return $ans; } sub lookupHostName { my $name = shift; my $qtype = shift; my $res = Net::DNS::Resolver->new; my @servers = $res->nameservers(); my $ans = $res->search ($name, $qtype); if (!defined ($ans)) { progress ("No results returned for $qtype lookup of $name\n"); progress ("Checked nameservers:\n"); foreach (@servers) { progress ("\t$_\n"); } return 1; } else { #progress ("Received answer:\n"); #progress ($ans->string()."\n"); return 0; } } sub setHostName { my $old = $config{HOSTNAME}; while (1) { $config{HOSTNAME} = askNonBlank("Please enter the logical hostname for this host", $config{HOSTNAME}); if (lookupHostName ($config{HOSTNAME}, 'A')) { progress("\n\nDNS ERROR resolving $config{HOSTNAME}\n"); progress("It is suggested that the hostname be resolvable via DNS\n"); if (askYN("Re-Enter hostname","Yes") eq "no") { last; } $config{HOSTNAME} = $old; } else {last;} } $config{HOSTNAME} = lc($config{HOSTNAME}); if ($config{SMTPHOST} eq $old) { $config{SMTPHOST} = $config{HOSTNAME}; } if ($config{SNMPTRAPHOST} eq $old) { $config{SNMPTRAPHOST} = $config{HOSTNAME}; } if ($config{LDAPHOST} eq $old) { changeLdapHost($config{HOSTNAME}); } if ($config{CREATEDOMAIN} eq $old) { $config{CREATEDOMAIN} = $config{HOSTNAME}; my ($u,$d) = split ('@', $config{CREATEADMIN}); $config{CREATEADMIN} = $u.'@'.$config{CREATEDOMAIN}; my ($u,$d) = split ('@', $config{AVUSER}); $config{AVUSER} = $u.'@'.$config{CREATEDOMAIN}; $config{AVDOMAIN} = $config{CREATEDOMAIN}; my ($u,$d) = split ('@', $config{TRAINSASPAM}); $config{TRAINSASPAM} = $u.'@'.$config{CREATEDOMAIN}; my ($u,$d) = split ('@', $config{TRAINSAHAM}); $config{TRAINSAHAM} = $u.'@'.$config{CREATEDOMAIN}; my ($u,$d) = split ('@', $config{VIRUSQUARANTINE}); $config{VIRUSQUARANTINE} = $u.'@'.$config{CREATEDOMAIN}; my ($u,$d) = split ('@', $config{zimbraBackupReportEmailRecipients}); $config{zimbraBackupReportEmailRecipients} = $u.'@'.$config{CREATEDOMAIN}; my ($u,$d) = split ('@', $config{zimbraBackupReportEmailRecipients}); $config{zimbraBackupReportEmailRecipients} = $u.'@'.$config{CREATEDOMAIN}; } my ($suser,$sdomain) = split ('@', $config{SMTPSOURCE}, 2); if ($sdomain eq $old) { $config{SMTPSOURCE} = $suser.'@'.$config{CREATEDOMAIN}; } ($suser,$sdomain) = split ('@', $config{SMTPDEST}, 2); if ($sdomain eq $old) { $config{SMTPDEST} = $suser.'@'.$config{CREATEDOMAIN}; } if ($config{SPELLURL} eq "http://${old}:7780/aspell.php") { $config{SPELLURL} = "http://$config{HOSTNAME}:7780/aspell.php"; } } sub setSmtpHost { $config{SMTPHOST} = askNonBlank("Please enter the SMTP server hostname:", $config{SMTPHOST}); } sub setLdapHost { changeLdapHost( askNonBlank("Please enter the ldap server hostname:", $config{LDAPHOST})); } sub setLdapPort { changeLdapPort( askNum("Please enter the ldap server port:", $config{LDAPPORT})); } sub setLdapServerID { changeLdapServerID(askPositiveInt("Please enter the ldap Server ID:", $config{LDAPSERVERID})); } sub setLdapReplicationType { while (1) { my $m = askNonBlank("Please enter the LDAP replication type (replica, mmr)", $config{LDAPREPLICATIONTYPE}); if ($m eq "replica" || $m eq "mmr") { $config{LDAPREPLICATIONTYPE} = $m; return; } print "Please enter a valid replication type!\n"; } } sub setHttpPort { $config{HTTPPORT} = askNum("Please enter the HTTP server port:", $config{HTTPPORT}); if($config{HTTPPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{HTTPPORT} == $config{HTTPPROXYPORT}) { $config{HTTPPROXYPORT}="UNSET"; } } elsif (isInstalled("zimbra-store") && !isInstalled("zimbra-proxy")) { if($config{HTTPPORT} == $config{HTTPPROXYPORT}) { if ($config{HTTPPORT} > 8000) { $config{HTTPPROXYPORT} = $config{HTTPPORT} - 8000; } else { $config{HTTPPROXYPORT} = $config{HTTPPORT} + 8000; } } } } sub setHttpsPort { $config{HTTPSPORT} = askNum("Please enter the HTTPS server port:", $config{HTTPSPORT}); if($config{HTTPPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{HTTPSPORT} == $config{HTTPSPROXYPORT}) { $config{HTTPSPROXYPORT}="UNSET"; } } elsif (isInstalled("zimbra-store") && !isInstalled("zimbra-proxy")) { if($config{HTTPSPORT} == $config{HTTPSPROXYPORT}) { if ($config{HTTPSPORT} > 8000) { $config{HTTPSPROXYPORT} = $config{HTTPSPORT} - 8000; } else { $config{HTTPSPROXYPORT} = $config{HTTPSPORT} + 8000; } } } } sub setImapPort { $config{IMAPPORT} = askNum("Please enter the IMAP server port:", $config{IMAPPORT}); if($config{MAILPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{IMAPPORT} == $config{IMAPPROXYPORT}) { $config{IMAPPROXYPORT}="UNSET"; } } elsif (isInstalled("zimbra-store") && !isInstalled("zimbra-proxy")) { if($config{IMAPPORT} == $config{IMAPPROXYPORT}) { if ($config{IMAPPORT} > 7000) { $config{IMAPPROXYPORT} = $config{IMAPPORT} - 7000; } else { $config{IMAPPROXYPORT} = $config{IMAPPORT} + 7000; } } } } sub setImapSSLPort { $config{IMAPSSLPORT} = askNum("Please enter the IMAP SSL server port:", $config{IMAPSSLPORT}); if($config{MAILPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT}) { $config{IMAPSSLPROXYPORT}="UNSET"; } } elsif (isInstalled("zimbra-store") && !isInstalled("zimbra-proxy")) { if($config{IMAPSSLPORT} == $config{IMAPSSLPROXYPORT}) { if ($config{IMAPSSLPORT} > 7000) { $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPORT} - 7000; } else { $config{IMAPSSLPROXYPORT} = $config{IMAPSSLPORT} + 7000; } } } } sub setPopPort { $config{POPPORT} = askNum("Please enter the POP server port:", $config{POPPORT}); if($config{MAILPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{POPPORT} == $config{POPPROXYPORT}) { $config{POPPROXYPORT}="UNSET"; } } elsif (isInstalled("zimbra-store") && !isInstalled("zimbra-proxy")) { if($config{POPPORT} == $config{POPPROXYPORT}) { if ($config{POPPORT} > 7000) { $config{POPPROXYPORT} = $config{POPPORT} - 7000; } else { $config{POPPROXYPORT} = $config{POPPORT} + 7000; } } } } sub setPopSSLPort { $config{POPSSLPORT} = askNum("Please enter the POP SSL server port:", $config{POPSSLPORT}); if($config{MAILPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{POPSSLPORT} == $config{POPSSLPROXYPORT}) { $config{POPSSLPROXYPORT}="UNSET"; } } elsif (isInstalled("zimbra-store") && !isInstalled("zimbra-proxy")) { if($config{POPSSLPORT} == $config{POPSSLPROXYPORT}) { if ($config{POPSSLPORT} > 7000) { $config{POPSSLPROXYPORT} = $config{POPSSLPORT} - 7000; } else { $config{POPSSLPROXYPORT} = $config{POPSSLPORT} + 7000; } } } } sub setImapProxyPort { $config{IMAPPROXYPORT} = askNum("Please enter the IMAP Proxy server port:", $config{IMAPPROXYPORT}); if($config{MAILPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{IMAPPROXYPORT} == $config{IMAPPORT}) { $config{IMAPPORT}="UNSET"; } } } sub setImapSSLProxyPort { $config{IMAPSSLPROXYPORT} = askNum("Please enter the IMAP SSL Proxy server port:", $config{IMAPSSLPROXYPORT}); if($config{MAILPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{IMAPSSLPROXYPORT} == $config{IMAPSSLPORT}) { $config{IMAPSSLPORT}="UNSET"; } } } sub setPopProxyPort { $config{POPPROXYPORT} = askNum("Please enter the POP Proxy server port:", $config{POPPROXYPORT}); if($config{MAILPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{POPPROXYPORT} == $config{POPPORT}) { $config{POPPORT}="UNSET"; } } } sub setPopSSLProxyPort { $config{POPSSLPROXYPORT} = askNum("Please enter the POP SSL Proxyserver port:", $config{POPSSLPROXYPORT}); if($config{MAILPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{POPSSLPROXYPORT} == $config{POPSSLPORT}) { $config{POPSSLPORT}="UNSET"; } } } sub setHttpProxyPort { $config{HTTPPROXYPORT} = askNum("Please enter the HTTP Proxyserver port:", $config{HTTPPROXYPORT}); if($config{HTTPPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{HTTPPROXYPORT} == $config{HTTPPORT}) { $config{HTTPPORT}="UNSET"; } } } sub setHttpsProxyPort { $config{HTTPSPROXYPORT} = askNum("Please enter the HTTPS Proxyserver port:", $config{HTTPSPROXYPORT}); if($config{HTTPPROXY} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE") { if($config{HTTPSPROXYPORT} == $config{HTTPSPORT}) { $config{HTTPSPORT}="UNSET"; } } } sub setSpellUrl { $config{SPELLURL} = askNonBlank("Please enter the spell server URL:", $config{SPELLURL}); } sub setLicenseFile { $config{LICENSEFILE} = askFileName("Enter the name of the file that contains the license:", $config{LICENSEFILE}); system("cp $config{LICENSEFILE} /opt/zimbra/conf/ZCSLicense.xml") if ($config{LICENSEFILE} ne "/opt/zimbra/conf/ZCSLicense.xml"); if ( -f "/opt/zimbra/conf/ZCSLicense.xml") { qx(chown zimbra:zimbra /opt/zimbra/conf/ZCSLicense.xml); qx(chmod 444 /opt/zimbra/conf/ZCSLicense.xml); } } sub setTimeZone { my $timezones="/opt/zimbra/conf/timezones.ics"; if (-f $timezones) { detail("Loading default list of timezones.\n"); my $tz = new Zimbra::Util::Timezone; $tz->parse; my $new; # build a hash of the timezone objects with a unique number as the value my %TZID = undef; my $ctr=1; $TZID{$_} = $ctr++ foreach sort $tz->dump; my %RTZID = reverse %TZID; # get a reference to the default value or attempt to lookup the system locale. detail("Previous TimeZoneID $config{zimbraPrefTimeZoneId}\n"); my $ltzref=$tz->gettzbyid("$config{zimbraPrefTimeZoneId}"); unless (defined $ltzref) { detail ("Determining system locale.\n"); my $localtzname=qx(/bin/date '+%Z'); chomp($localtzname); detail("DEBUG: Local tz name $localtzname\n"); $ltzref=$tz->gettzbyname($localtzname); } # look up the current value and present a list my $default = $TZID{$ltzref->tzid} || "21"; while ($new eq "") { foreach (sort {$TZID{$a} <=> $TZID{$b}} keys %TZID) { print "$TZID{$_} $_\n"; } my $ans=askNum("Enter the number for the local timezone:", $default); $new = $RTZID{$ans}; } $config{zimbraPrefTimeZoneId} = $new; } } sub setIPMode { while (1) { my $new = askPassword("IP Mode for Zimbra (ipv4, both, ipv6):", $config{zimbraIPMode}); if ($new eq "ipv4" || $new eq "both" || $new eq "ipv6") { if ($config{zimbraIPMode} ne $new) { $config{zimbraIPMode} = $new; } return; } else { print "IP Mode must be one of ipv4, both, or ipv6!\n"; } } } sub setSSLDefaultDigest { while (1) { my $new = askPassword("Default OpenSSL digest:", $config{ssl_default_digest}); my $ssl_digests= join(' ', @ssl_digests); if ($ssl_digests =~ /\b$new\b/) { if ($config{ssl_default_digest} ne $new) { $config{ssl_default_digest} = $new; } return; } else { print "Valid digest modes are: $ssl_digests!\n"; } } } sub setEnabledDependencies { if (isEnabled("zimbra-ldap")) { if ($config{LDAPHOST} eq "") { changeLdapHost($config{HOSTNAME}); } } else { if ($config{LDAPHOST} eq $config{HOSTNAME}) { changeLdapHost(""); $config{LDAPADMINPASS} = ""; $config{LDAPROOTPASS} = ""; } } if (isEnabled("zimbra-store")) { if (isEnabled("zimbra-mta")) { $config{SMTPHOST} = $config{HOSTNAME}; } if ($config{"zimbraMailProxy"} eq "TRUE" || $config{"zimbraWebProxy"} eq "TRUE") { setUseProxy(); } } if (isEnabled("zimbra-mta")) { if ($newinstall) { $config{RUNAV} = "yes"; $config{RUNSA} = "yes"; $config{RUNDKIM} = "yes"; $config{RUNARCHIVING} = "no"; $config{RUNCBPOLICYD} = "no"; } else { $config{RUNSA} = (isServiceEnabled("antispam") ? "yes" : "no"); $config{RUNAV} = (isServiceEnabled("antivirus") ? "yes" : "no"); if ($config{RUNDKIM} ne "yes") { $config{RUNDKIM} = (isServiceEnabled("opendkim") ? "yes" : "no"); } $config{RUNARCHIVING} = (isServiceEnabled("archiving") ? "yes" : "no"); $config{RUNCBPOLICYD} = (isServiceEnabled("cbpolicyd") ? "yes" : "no"); } } if (isEnabled("zimbra-core")) { if ($newinstall) { $config{RUNVMHA} = "no"; } else { if(isNetwork()) { $config{RUNVMHA} = (isServiceEnabled("vmware-ha") ? "yes" : "no"); } else { $config{RUNVMHA} = "no"; } } } if (isEnabled("zimbra-spell")) { $config{USESPELL} = "yes"; $config{SPELLURL} = "http://$config{HOSTNAME}:7780/aspell.php"; } if (isInstalled("zimbra-proxy")) { setUseProxy(); } } sub toggleEnabled { my $p = shift; $enabledPackages{$p} = (isEnabled($p))?"Disabled":"Enabled"; setEnabledDependencies(); } sub verifyQuit { if (askYN("Quit without applying changes?", "No") eq "yes") {return 1;} return 0; } sub genPackageMenu { my $package = shift; my %lm = (); $lm{menuitems}{1} = { "prompt" => "Status:", "var" => \$enabledPackages{$package}, "callback" => \&toggleEnabled, "arg" => $package}; $lm{promptitem} = { "selector" => "r", "prompt" => "Select, or 'r' for previous menu ", "action" => "return"}; $lm{default} = "r"; return \%lm; } sub genSubMenu { my %lm = (); $lm{promptitem} = { "selector" => "r", "prompt" => "Select, or 'r' for previous menu ", "action" => "return"}; $lm{default} = "r"; return \%lm; } sub isNetwork { return((-f "/opt/zimbra/bin/zmbackup") ? 1 : 0); } sub isLdapMaster { return(($config{LDAPHOST} eq $config{HOSTNAME}) ? 1 : 0); } sub isZCS { return((grep(/\b\w+-store\b/,@packageList)) ? 1 : 0); } sub isZCA { return (glob("/opt/vmware-zca-installer/conf/optConfig/*.cfg") ? 1 : 0); } sub isFoss { return((-f "/opt/zimbra/bin/zmbackup") ? 0 : 1); } sub isLicenseDaemonConfigured { return isInstalled("zimbra-license-daemon") && isEnabled("zimbra-license-daemon") && -d "/opt/zimbra/license"; } sub isLicenseActivated { runAsZimbra("/opt/zimbra/bin/zmlicensectl --service restart") if isLicenseDaemonConfigured() && !$newinstall; my $status = runAsZimbra("/opt/zimbra/bin/zmlicense -c >/dev/null") ? 0 : 1; runAsZimbra("/opt/zimbra/bin/zmlicensectl --service stop") if isLicenseDaemonConfigured() && !$newinstall; return $status; } sub createPackageMenu { my $package = shift; if ($package eq "zimbra-ldap") { return createLdapMenu($package); } elsif ($package eq "zimbra-mta") { return createMtaMenu($package); } elsif ($package eq "zimbra-snmp") { return createSnmpMenu($package); } elsif ($package eq "zimbra-store") { return createStoreMenu($package); } elsif ($package eq "zimbra-proxy") { return createProxyMenu($package); } elsif ($package eq "zimbra-dnscache") { return createDNSCacheMenu($package); } elsif ($package eq "zimbra-imapd") { return createImapMenu($package); } elsif ($package eq "zimbra-onlyoffice") { return createOnlyofficeMenu($package); } } sub createCommonMenu { my $package = shift; my $lm = genSubMenu(); $$lm{title} = "Common configuration"; $$lm{createsub} = \&createCommonMenu; $$lm{createarg} = $package; my $i = 1; $$lm{menuitems}{$i} = { "prompt" => "Hostname:", "var" => \$config{HOSTNAME}, "callback" => \&setHostName }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Ldap master host:", "var" => \$config{LDAPHOST}, "callback" => \&setLdapHost }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Ldap port:", "var" => \$config{LDAPPORT}, "callback" => \&setLdapPort }; $i++; if ($config{LDAPADMINPASS} eq "") { $config{LDAPADMINPASSSET} = "UNSET"; } else { $config{LDAPADMINPASSSET} = "set" unless ($config{LDAPADMINPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Ldap Admin password:", "var" => \$config{LDAPADMINPASSSET}, "callback" => \&setLdapAdminPass }; $i++; # ldap users if (!defined($installedPackages{"zimbra-ldap"})) { $$lm{menuitems}{$i} = { "prompt" => "LDAP Base DN:", "var" => \$config{ldap_dit_base_dn_config}, "callback" => \&setLdapBaseDN, }; $i++; } $config{USEEPHEMERALSTORE} = "no" unless (exists $config{USEEPHEMERALSTORE}); $$lm{menuitems}{$i} = { "prompt" => "Store ephemeral attributes outside Ldap:", "var" => \$config{USEEPHEMERALSTORE}, "callback" => \&toggleYN, "arg" => "USEEPHEMERALSTORE", }; $i++; if ($config{USEEPHEMERALSTORE} eq "yes") { $$lm{menuitems}{$i} = { "prompt" => "Value for zimbraEphemeralBackendURL:", "var" => \$config{EphemeralBackendURL}, "callback" => \&setEphemeralBackendURL, }; $i++; } # interprocess security $$lm{menuitems}{$i} = { "prompt" => "Secure interprocess communications:", "var" => \$config{ZIMBRA_REQ_SECURITY}, "callback" => \&toggleYN, "arg" => "ZIMBRA_REQ_SECURITY", }; $i++; if ($config{ZIMBRA_REQ_SECURITY} eq "yes") { $config{zimbra_require_interprocess_security} = 1; } else { $config{zimbra_require_interprocess_security} = 0; $starttls=0; } $$lm{menuitems}{$i} = { "prompt" => "TimeZone:", "var" => \$config{zimbraPrefTimeZoneId}, "callback" => \&setTimeZone }; $i++; $$lm{menuitems}{$i} = { "prompt" => "IP Mode:", "var" => \$config{zimbraIPMode}, "callback" => \&setIPMode }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Default SSL digest:", "var" => \$config{ssl_default_digest}, "callback" => \&setSSLDefaultDigest }; $i++; return $lm; } sub createOnlyofficeMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "Onlyoffice configuration"; $$lm{createsub} = \&createOnlyofficeMenu; $$lm{createarg} = $package; my $i = 2; if (isEnabled($package)) { # get the hostname for onlyoffice to be put into config # if standalone server : # 1. global config already present, do not override # 2. global config not present, this server name goes as global config # if not standalone: # set the server host name at server level config if (isEnabled("zimbra-store")) { $config{ONLYOFFICESTANDALONE} = "no"; } else { $config{ONLYOFFICESTANDALONE} = "yes"; } if ($config{ONLYOFFICEHOSTNAME} eq "") { $config{ONLYOFFICEHOSTNAME} = $config{HOSTNAME}; } $$lm{menuitems}{$i} = { "prompt" => "Onlyoffice server:", "var" => \$config{ONLYOFFICEHOSTNAME}, "callback" => \&setOnlyOfficeHost }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Standalone Onlyoffice:", "var" => \$config{ONLYOFFICESTANDALONE} }; $i++; } return $lm; } sub createLdapMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "Ldap configuration"; $$lm{createsub} = \&createLdapMenu; $$lm{createarg} = $package; my $i = 2; if (isEnabled($package)) { $$lm{menuitems}{$i} = { "prompt" => "Create Domain:", "var" => \$config{DOCREATEDOMAIN}, "callback" => \&toggleYN, "arg" => "DOCREATEDOMAIN", }; $i++; if ($config{DOCREATEDOMAIN} eq "yes") { $$lm{menuitems}{$i} = { "prompt" => "Domain to create:", "var" => \$config{CREATEDOMAIN}, "callback" => \&setCreateDomain, }; $i++; } #$$lm{menuitems}{$i} = { #"prompt" => "Sync domain GALs to contact folders:", #"var" => \$config{ENABLEGALSYNCACCOUNTS}, #"callback" => \&toggleYN, #"arg" => "ENABLEGALSYNCACCOUNTS", #}; #$i++; if($config{LDAPREPLICATIONTYPE} ne "master") { $$lm{menuitems}{$i} = { "prompt" => "Ldap replication type:", "var" => \$config{LDAPREPLICATIONTYPE}, "callback" => \&setLdapReplicationType }; $i++; } if ($config{LDAPREPLICATIONTYPE} eq "mmr") { $$lm{menuitems}{$i} = { "prompt" => "Ldap Server ID:", "var" => \$config{LDAPSERVERID}, "callback" => \&setLdapServerID }; $i++; } if ($config{LDAPROOTPASS} ne "") { $config{LDAPROOTPASSSET} = "set"; } else { $config{LDAPROOTPASSSET} = "UNSET" unless ($config{LDAPROOTPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Ldap root password:", "var" => \$config{LDAPROOTPASSSET}, "callback" => \&setLdapRootPass }; $i++; if ($config{LDAPREPPASS} eq "") { $config{LDAPREPPASSSET} = "UNSET"; } else { $config{LDAPREPPASSSET} = "set" unless ($config{LDAPREPPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Ldap replication password:", "var" => \$config{LDAPREPPASSSET}, "callback" => \&setLdapRepPass }; $i++; if ($config{HOSTNAME} eq $config{LDAPHOST} || $config{LDAPREPLICATIONTYPE} ne "replica" || isEnabled("zimbra-mta")) { if ($config{LDAPPOSTPASS} eq "") { $config{LDAPPOSTPASSSET} = "UNSET"; } else { $config{LDAPPOSTPASSSET} = "set" unless ($config{LDAPPOSTPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Ldap postfix password:", "var" => \$config{LDAPPOSTPASSSET}, "callback" => \&setLdapPostPass }; $i++; if ($config{LDAPAMAVISPASS} eq "") { $config{LDAPAMAVISPASSSET} = "UNSET"; } else { $config{LDAPAMAVISPASSSET} = "set" unless ($config{LDAPAMAVISPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Ldap amavis password:", "var" => \$config{LDAPAMAVISPASSSET}, "callback" => \&setLdapAmavisPass }; $i++; } if ($config{HOSTNAME} eq $config{LDAPHOST} || $config{LDAPREPLICATIONTYPE} ne "replica" || isEnabled("zimbra-proxy")) { if ($config{ldap_nginx_password} eq "") { $config{LDAPNGINXPASSSET} = "UNSET"; } else { $config{LDAPNGINXPASSSET} = "set" unless ($config{LDAPNGINXPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Ldap nginx password:", "var" => \$config{LDAPNGINXPASSSET}, "callback" => \&setLdapNginxPass }; $i++; } if ($config{HOSTNAME} eq $config{LDAPHOST} || $config{LDAPREPLICATIONTYPE} ne "replica" ) { if ($config{ldap_bes_searcher_password} eq "") { $config{LDAPBESSEARCHSET} = "UNSET"; } else { $config{LDAPBESSEARCHSET} = "set" unless ($config{LDAPBESSEARCHSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Ldap Bes Searcher password:", "var" => \$config{LDAPBESSEARCHSET}, "callback" => \&setLdapBesSearchPass }; $i++; } } return $lm; } sub createCOSMenu { my $package = shift; my $lm = genSubMenu(); $$lm{title} = "Default Class of Service configuration"; $$lm{createsub} = \&createCOSMenu; $$lm{createarg} = $package; my $i = 1; $$lm{menuitems}{$i} = { "prompt" => "Enable Tasks Feature:", "var" => \$config{zimbraFeatureTasksEnabled}, "callback" => \&toggleConfigEnabled, "arg" => "zimbraFeatureTasksEnabled", }; $i++; return $lm; } sub createLdapUsersMenu { my $package = shift; my $lm = genSubMenu(); $$lm{title} = "Ldap Users configuration"; $$lm{createsub} = \&createLdapUsersMenu; $$lm{createarg} = $package; my $i = 1; return $lm; } sub createArchivingMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "Archiving configuration"; $$lm{createsub} = \&createArchivingMenu; $$lm{createarg} = $package; my $i = 2; return $lm; } sub createSnmpMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "Snmp configuration"; $$lm{createsub} = \&createSnmpMenu; $$lm{createarg} = $package; my $i = 2; if (isEnabled($package)) { $$lm{menuitems}{$i} = { "prompt" => "Enable SNMP notifications:", "var" => \$config{SNMPNOTIFY}, "callback" => \&toggleYN, "arg" => "SNMPNOTIFY", }; $i++; if ($config{SNMPNOTIFY} eq "yes") { $$lm{menuitems}{$i} = { "prompt" => "SNMP Trap hostname:", "var" => \$config{SNMPTRAPHOST}, "callback" => \&setSnmpTrapHost, }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "Enable SMTP notifications:", "var" => \$config{SMTPNOTIFY}, "callback" => \&toggleYN, "arg" => "SMTPNOTIFY", }; $i++; if ($config{SMTPNOTIFY} eq "yes") { $$lm{menuitems}{$i} = { "prompt" => "SMTP Source email address:", "var" => \$config{SMTPSOURCE}, "callback" => \&setSmtpSource, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "SMTP Destination email address:", "var" => \$config{SMTPDEST}, "callback" => \&setSmtpDest, }; $i++; } } return $lm; } sub createMtaMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "Mta configuration"; $$lm{createsub} = \&createMtaMenu; $$lm{createarg} = $package; my $i = 2; if (isEnabled($package)) { $$lm{menuitems}{$i} = { "prompt" => "Enable Spamassassin:", "var" => \$config{RUNSA}, "callback" => \&toggleYN, "arg" => "RUNSA", }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Enable Clam AV:", "var" => \$config{RUNAV}, "callback" => \&toggleYN, "arg" => "RUNAV", }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Enable OpenDKIM:", "var" => \$config{RUNDKIM}, "callback" => \&toggleYN, "arg" => "RUNDKIM", }; $i++; if ($config{RUNAV} eq "yes") { $$lm{menuitems}{$i} = { "prompt" => "Notification address for AV alerts:", "var" => \$config{AVUSER}, "callback" => \&setAvUser, }; $i++; } if (isEnabled("zimbra-archiving") || isComponentAvailable("archiving")) { $$lm{menuitems}{$i} = { "prompt" => "Enable Archiving and Discovery:", "var" => \$config{RUNARCHIVING}, "callback" => \&toggleYN, "arg" => "RUNARCHIVING", }; $i++; } if ($config{LDAPPOSTPASS} eq "") { $config{LDAPPOSTPASSSET} = "UNSET"; } else { $config{LDAPPOSTPASSSET} = "set" unless ($config{LDAPPOSTPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Bind password for postfix ldap user:", "var" => \$config{LDAPPOSTPASSSET}, "callback" => \&setLdapPostPass }; $i++; if ($config{LDAPAMAVISPASS} eq "") { $config{LDAPAMAVISPASSSET} = "UNSET"; } else { $config{LDAPAMAVISPASSSET} = "set" unless ($config{LDAPAMAVISPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Bind password for amavis ldap user:", "var" => \$config{LDAPAMAVISPASSSET}, "callback" => \&setLdapAmavisPass }; $i++; } return $lm; } sub createProxyMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "Proxy configuration"; $$lm{createsub} = \&createProxyMenu; $$lm{createarg} = $package; my $i = 2; if (isInstalled($package)) { $$lm{menuitems}{$i} = { "prompt" => "Enable POP/IMAP Proxy:", "var" => \$config{MAILPROXY}, "callback" => \&toggleTF, "arg" => "MAILPROXY", }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Enable strict server name enforcement?", "var" => \$config{STRICTSERVERNAMEENABLED}, "callback" => \&toggleYN, "arg" => "STRICTSERVERNAMEENABLED", }; $i++; if($config{MAILPROXY} eq "TRUE") { if(!isEnabled("zimbra-store")) { $$lm{menuitems}{$i} = { "prompt" => "IMAP server port:", "var" => \$config{IMAPPORT}, "callback" => \&setImapPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "IMAP server SSL port:", "var" => \$config{IMAPSSLPORT}, "callback" => \&setImapSSLPort, }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "IMAP proxy port:", "var" => \$config{IMAPPROXYPORT}, "callback" => \&setImapProxyPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "IMAP SSL proxy port:", "var" => \$config{IMAPSSLPROXYPORT}, "callback" => \&setImapSSLProxyPort, }; $i++; if(!isEnabled("zimbra-store")) { $$lm{menuitems}{$i} = { "prompt" => "POP server port:", "var" => \$config{POPPORT}, "callback" => \&setPopPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "POP server SSL port:", "var" => \$config{POPSSLPORT}, "callback" => \&setPopSSLPort, }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "POP proxy port:", "var" => \$config{POPPROXYPORT}, "callback" => \&setPopProxyPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "POP SSL proxy port:", "var" => \$config{POPSSLPROXYPORT}, "callback" => \&setPopSSLProxyPort, }; $i++; } if ($config{HTTPPROXY} eq "TRUE" || $config{MAILPROXY} eq "TRUE") { if ($config{ldap_nginx_password} eq "") { $config{LDAPNGINXPASSSET} = "UNSET"; } else { $config{LDAPNGINXPASSSET} = "set" unless ($config{LDAPNGINXPASSSET} eq "Not Verified"); } $$lm{menuitems}{$i} = { "prompt" => "Bind password for nginx ldap user:", "var" => \$config{LDAPNGINXPASSSET}, "callback" => \&setLdapNginxPass }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "Enable HTTP[S] Proxy:", "var" => \$config{HTTPPROXY}, "callback" => \&toggleTF, "arg" => "HTTPPROXY", }; $i++; if ($config{HTTPPROXY} eq "TRUE") { if(!isEnabled("zimbra-store")) { $$lm{menuitems}{$i} = { "prompt" => "Web server HTTP port:", "var" => \$config{HTTPPORT}, "callback" => \&setHttpPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Web server HTTPS port:", "var" => \$config{HTTPSPORT}, "callback" => \&setHttpsPort, }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "HTTP proxy port:", "var" => \$config{HTTPPROXYPORT}, "callback" => \&setHttpProxyPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "HTTPS proxy port:", "var" => \$config{HTTPSPROXYPORT}, "callback" => \&setHttpsProxyPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Proxy server mode:", "var" => \$config{PROXYMODE}, "callback" => \&setProxyMode, }; $i++; } } return $lm; } sub createDNSCacheMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "DNS Cache configuration"; $$lm{createsub} = \&createDNSCacheMenu; $$lm{createarg} = $package; my $i = 2; if (isEnabled($package)) { $$lm{menuitems}{$i} = { "prompt" => "Master DNS IP address(es):", "var" => \$config{zimbraDNSMasterIP}, "callback" => \&setMasterDNSIP, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Enable DNS lookups over TCP:", "var" => \$config{zimbraDNSUseTCP}, "callback" => \&toggleYN, "arg" => "zimbraDNSUseTCP", }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Enable DNS lookups over UDP:", "var" => \$config{zimbraDNSUseUDP}, "callback" => \&toggleYN, "arg" => "zimbraDNSUseUDP", }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Only allow TCP to communicate with Master DNS:", "var" => \$config{zimbraDNSTCPUpstream}, "callback" => \&toggleYN, "arg" => "zimbraDNSTCPUpstream", }; $i++; } return $lm; } sub createImapMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "IMAPD configuration"; $$lm{createsub} = \&createImapMenu; $$lm{createarg} = $package; my $i = 2; if (isEnabled($package)) { $$lm{menuitems}{$i} = { "prompt" => "Add to upstream IMAP Servers?:", "var" => \$config{DOADDUPSTREAMIMAP}, "callback" => \&toggleYN, "arg" => "DOADDUPSTREAMIMAP", }; $i++; } return $lm; } sub createStoreMenu { my $package = shift; my $lm = genPackageMenu($package); $$lm{title} = "Store configuration"; $$lm{createsub} = \&createStoreMenu; $$lm{createarg} = $package; my $i = 2; if (isEnabled($package)) { $$lm{menuitems}{$i} = { "prompt" => "Create Admin User:", "var" => \$config{DOCREATEADMIN}, "callback" => \&toggleYN, "arg" => "DOCREATEADMIN", }; $i++; if ($config{DOCREATEADMIN} eq "yes") { $$lm{menuitems}{$i} = { "prompt" => "Admin user to create:", "var" => \$config{CREATEADMIN}, "callback" => \&setCreateAdmin }; $i++; if ($config{CREATEADMINPASS} ne "") { $config{ADMINPASSSET} = "set"; } else { $config{ADMINPASSSET} = "UNSET"; } $$lm{menuitems}{$i} = { "prompt" => "Admin Password", "var" => \$config{ADMINPASSSET}, "callback" => \&setAdminPass }; $i++; } my $ldap_virusquarantine = getLdapConfigValue("zimbraAmavisQuarantineAccount") if (ldapIsAvailable()); if ($ldap_virusquarantine eq "") { $$lm{menuitems}{$i} = { "prompt" => "Anti-virus quarantine user:", "var" => \$config{VIRUSQUARANTINE}, "callback" => \&setAmavisVirusQuarantine }; $i++; } else { $config{VIRUSQUARANTINE} = $ldap_virusquarantine; } $$lm{menuitems}{$i} = { "prompt" => "Enable automated spam training:", "var" => \$config{DOTRAINSA}, "callback" => \&toggleYN, "arg" => "DOTRAINSA", }; $i++; if ($config{DOTRAINSA} eq "yes") { my $ldap_trainsaspam = getLdapConfigValue("zimbraSpamIsSpamAccount") if (ldapIsAvailable()); if ($ldap_trainsaspam eq "") { $$lm{menuitems}{$i} = { "prompt" => "Spam training user:", "var" => \$config{TRAINSASPAM}, "callback" => \&setTrainSASpam }; $i++; } else { $config{TRAINSASPAM} = $ldap_trainsaspam; } my $ldap_trainsaham = getLdapConfigValue("zimbraSpamIsNotSpamAccount") if (ldapIsAvailable()); if ($ldap_trainsaham eq "") { $$lm{menuitems}{$i} = { "prompt" => "Non-spam(Ham) training user:", "var" => \$config{TRAINSAHAM}, "callback" => \&setTrainSAHam }; $i++; } else { $config{TRAINSAHAM} = $ldap_trainsaham; } } $$lm{menuitems}{$i} = { "prompt" => "SMTP host:", "var" => \$config{SMTPHOST}, "callback" => \&setSmtpHost, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Web server HTTP port:", "var" => \$config{HTTPPORT}, "callback" => \&setHttpPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Web server HTTPS port:", "var" => \$config{HTTPSPORT}, "callback" => \&setHttpsPort, }; $i++; if(!isEnabled("zimbra-proxy") && $config{"zimbraWebProxy"} eq "TRUE") { $$lm{menuitems}{$i} = { "prompt" => "HTTP proxy port:", "var" => \$config{HTTPPROXYPORT}, "callback" => \&setHttpProxyPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "HTTPS proxy port:", "var" => \$config{HTTPSPROXYPORT}, "callback" => \&setHttpsProxyPort, }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "Web server mode:", "var" => \$config{MODE}, "callback" => \&setStoreMode, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "IMAP server port:", "var" => \$config{IMAPPORT}, "callback" => \&setImapPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "IMAP server SSL port:", "var" => \$config{IMAPSSLPORT}, "callback" => \&setImapSSLPort, }; $i++; if(!isEnabled("zimbra-proxy") && $config{"zimbraMailProxy"} eq "TRUE") { $$lm{menuitems}{$i} = { "prompt" => "IMAP proxy port:", "var" => \$config{IMAPPROXYPORT}, "callback" => \&setImapProxyPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "IMAP SSL proxy port:", "var" => \$config{IMAPSSLPROXYPORT}, "callback" => \&setImapSSLProxyPort, }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "POP server port:", "var" => \$config{POPPORT}, "callback" => \&setPopPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "POP server SSL port:", "var" => \$config{POPSSLPORT}, "callback" => \&setPopSSLPort, }; $i++; if(!isEnabled("zimbra-proxy") && $config{"zimbraMailProxy"} eq "TRUE") { $$lm{menuitems}{$i} = { "prompt" => "POP proxy port:", "var" => \$config{POPPROXYPORT}, "callback" => \&setPopProxyPort, }; $i++; $$lm{menuitems}{$i} = { "prompt" => "POP SSL proxy port:", "var" => \$config{POPSSLPROXYPORT}, "callback" => \&setPopSSLProxyPort, }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "Use spell check server:", "var" => \$config{USESPELL}, "callback" => \&toggleYN, "arg" => "USESPELL", }; $i++; if ($config{USESPELL} eq "yes") { $$lm{menuitems}{$i} = { "prompt" => "Spell server URL:", "var" => \$config{SPELLURL}, "callback" => \&setSpellUrl, }; $i++; } if (!isInstalled("zimbra-proxy") && $newinstall) { $$lm{menuitems}{$i} = { "prompt" => "Configure for use with mail proxy:", "var" => \$config{zimbraMailProxy}, "callback" => \&toggleTF, "arg" => "zimbraMailProxy", }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Configure for use with web proxy:", "var" => \$config{zimbraWebProxy}, "callback" => \&toggleTF, "arg" => "zimbraWebProxy", }; $i++; } $$lm{menuitems}{$i} = { "prompt" => "Enable version update checks:", "var" => \$config{VERSIONUPDATECHECKS}, "callback" => \&toggleTF, "arg" => "VERSIONUPDATECHECKS", }; $i++; if ($config{VERSIONUPDATECHECKS} eq "TRUE") { $$lm{menuitems}{$i} = { "prompt" => "Enable version update notifications:", "var" => \$config{zimbraVersionCheckSendNotifications}, "callback" => \&toggleTF, "arg" => "zimbraVersionCheckSendNotifications", }; $i++; if ($config{zimbraVersionCheckSendNotifications} eq "TRUE") { my $version_dst_addr = getLdapConfigValue("zimbraVersionCheckNotificationEmail") if (ldapIsAvailable()); if ($version_dst_addr eq "") { $$lm{menuitems}{$i} = { "prompt" => "Version update notification email:", "var" => \$config{zimbraVersionCheckNotificationEmail}, "callback" => \&setVersionCheckNotificationEmail }; $i++; } else { $config{zimbraVersionCheckNotificationEmail} = $version_dst_addr; } my $version_src_addr = getLdapConfigValue("zimbraVersionCheckNotificationEmailFrom") if (ldapIsAvailable()); if ($version_src_addr eq "") { $$lm{menuitems}{$i} = { "prompt" => "Version update source email:", "var" => \$config{zimbraVersionCheckNotificationEmailFrom}, "callback" => \&setVersionCheckNotificationEmailFrom }; $i++; } else { $config{zimbraVersionCheckNotificationEmailFrom} = $version_src_addr; } } } $$lm{menuitems}{$i} = { "prompt" => "Install mailstore (service webapp):", "var" => \$config{SERVICEWEBAPP}, "callback" => \&toggleSERVICEWEBAPP, "arg" => "SERVICEWEBAPP" }; $i++; $$lm{menuitems}{$i} = { "prompt" => "Install UI (zimbra,zimbraAdmin webapps):", "var" => \$config{UIWEBAPPS}, "callback" => \&toggleYN, "arg" => "UIWEBAPPS" }; $i++; if (-e $license_file) { chomp($config{LICENSEKEY} = qx(cat $license_file)); $config{LICENSEACTIVATIONOPTION} = "1"; } if ($config{LICENSEACTIVATIONOPTION} eq "1") { $config{LICENSEACTIVATIONOPTIONMSG} = "Activate license with installation"; } elsif ($config{LICENSEACTIVATIONOPTION} eq "2") { $config{LICENSEACTIVATIONOPTIONMSG} = "Activate license after installation"; } else { $config{LICENSEACTIVATIONOPTIONMSG} = "UNSET"; } # only prompt for license if it is a network install, the license is not activated, and the skip_activation_check is not set to "yes". if (isNetwork() && !isLicenseActivated() && $skip_activation_check ne "yes") { $$lm{menuitems}{$i} = { "prompt" => "License Activation:", "var" => \$config{LICENSEACTIVATIONOPTIONMSG}, "callback" => \&chooseLicenseActivationOption, }; $i++; } } return $lm; } sub displaySubMenuItems { my $items = shift; my $parentmenuvar = shift; my $indent = shift; if (defined($$items{createsub})) { $items = &{$$items{createsub}}($$items{createarg}); } # print "$indent$$items{title}\n"; foreach my $i (sort menuSort keys %{$$items{menuitems}}) { if (defined($$items{menuitems}{$i}{var}) && $$items{menuitems}{$i}{var} == $parentmenuvar) {next;} my $len = 44-(length($indent)); my $v; my $ind = $indent; if (defined $$items{menuitems}{$i}{var}) { $v = ${$$items{menuitems}{$i}{var}}; if ($v eq "" || $v eq "none" || $v eq "UNSET") { $v = "UNSET"; $ind=~s/ /*/g; } if ($v eq "Not Verified") { $v = "Not Verified"; $ind=~s/ /*/g; } } printf ("%s +%-${len}s %-30s\n", $ind, $$items{menuitems}{$i}{prompt}, $v); if (defined ($$items{menuitems}{$i}{submenu}) ) { displaySubMenuItems($$items{menuitems}{$i}{submenu},"$indent "); } } } sub menuSort { if ( ($a eq int($a)) && ($b eq int($b)) ) { return $a <=> $b; } return $a cmp $b; } sub displayMenu { my $items = shift; while (1) { if (defined($$items{createsub})) { $items = &{$$items{createsub}}($$items{createarg}); } print "\n$$items{title}\n\n"; foreach my $i (sort menuSort keys %{$$items{menuitems}}) { my $v; my $ind = " "; if (defined $$items{menuitems}{$i}{var}) { $v = ${$$items{menuitems}{$i}{var}}; if ($v eq "" || $v eq "none" || $v eq "UNSET") { $v = "UNSET"; $ind="**"; } if ($v eq "Not Verified") { $ind="**"; } } my $subMenuCheck = 1; if (defined ($$items{menuitems}{$i}{submenu}) || defined ($$items{menuitems}{$i}{callback}) ) { if (defined ($$items{menuitems}{$i}{submenu})) { $subMenuCheck = checkMenuConfig($$items{menuitems}{$i}{submenu}); } printf ("${ind}%2s) %-40s %-30s\n", $i, $$items{menuitems}{$i}{prompt}, $v); } else { # Disabled items printf ("${ind} %-40s %-30s\n", $$items{menuitems}{$i}{prompt}, $v); } if ($config{EXPANDMENU} eq "yes" || !$subMenuCheck) { if (defined ($$items{menuitems}{$i}{submenu}) ) { displaySubMenuItems($$items{menuitems}{$i}{submenu}, $$items{menuitems}{$i}{var}," "); print "\n"; } } } if (defined($$items{lastitem})) { printf (" %2s) %-40s\n", $$items{lastitem}{selector}, $$items{lastitem}{prompt}); } my $menuprompt = "\n"; if (defined($$items{promptitem})) { $menuprompt .= $$items{promptitem}{prompt}; } else { $menuprompt .= "Select "; } if (defined($$items{help})) { $menuprompt .= " (? - help) "; } print "$menuprompt"; if (defined $$items{default}) { print "[$$items{default}] "; } my $r = <>; chomp $r; if ($r eq "") { $r = $$items{default}; } if ($r eq "") { next; } if ($r eq $$items{lastitem}{selector}) { if ($$items{lastitem}{action} eq "quit") { if (verifyQuit()) { exit 0; } } elsif ($$items{lastitem}{action} eq "return") { return; } } elsif (defined $$items{help} && $r eq "?") { print "\n\n"; print $$items{help}{helptext}; print "\n"; ask("Press any key to continue", ""); print "\n\n"; } elsif (defined $$items{promptitem} && $r eq $$items{promptitem}{selector}) { if (defined $$items{promptitem}{callback}) { &{$$items{promptitem}{callback}}($$items{promptitem}{arg}); } elsif (defined $$items{promptitem}{action}) { if ($$items{promptitem}{action} eq "quit") { if (verifyQuit()) { exit 0; } } elsif ($$items{promptitem}{action} eq "return") { return; } } } elsif (defined $$items{menuitems}{$r}) { print "\n"; if (defined $$items{menuitems}{$r}{callback}) { &{$$items{menuitems}{$r}{callback}}($$items{menuitems}{$r}{arg}); } elsif (defined ($$items{menuitems}{$r}{submenu})) { displayMenu($$items{menuitems}{$r}{submenu}); } } else { ask("Invalid selection! - press any key to continue", ""); print "\n\n"; } } } sub createMainMenu { my %mm = (); $mm{createsub} = \&createMainMenu; $mm{title} = "Main menu"; $mm{help} = { "selector" => "?", "prompt" => "Help", "action" => "help", "helptext" => "Main Menu help\n\n". "Items marked with ** MUST BE CONFIGURED prior to applying configuration\n\n". "", }; $mm{lastitem} = { "selector" => "q", "prompt" => "Quit", "action" => "quit", }; my $i = 1; my $submenu = createCommonMenu("zimbra-core"); $mm{menuitems}{$i} = { "prompt" => "Common Configuration:", "submenu" => $submenu, }; $i++; foreach my $package (@packageList) { if ($package eq "zimbra-core") {next;} if ($package eq "zimbra-apache") {next;} if ($package eq "zimbra-archiving") {next;} if ($package eq "zimbra-memcached") {next;} if (defined($installedPackages{$package})) { if ($package =~ /logger|spell|convertd|license-daemon/) { $mm{menuitems}{$i} = { "prompt" => "$package:", "var" => \$enabledPackages{$package}, "callback" => \&toggleEnabled, "arg" => $package }; $i++; next; } my $submenu = createPackageMenu($package); $mm{menuitems}{$i} = { "prompt" => "$package:", "var" => \$enabledPackages{$package}, "submenu" => $submenu, }; $i++; } else { #push @mm, "$package not installed"; } } if (defined($installedPackages{"zimbra-core"}) && isNetwork()) { # simple test to see if we are running in a VM. if ( -x "/usr/lib/vmware-tools/sbin64/vmware-checkvm") { my $rc = runAsRoot("/usr/lib/vmware-tools/sbin64/vmware-checkvm"); if ($rc == 0) { $mm{menuitems}{$i} = { "prompt" => "Enable VMware HA:", "var" => \$config{RUNVMHA}, "callback" => \&toggleYN, "arg" => "RUNVMHA", }; $i++; } } } if (defined($installedPackages{"zimbra-store"})) { my $submenu = createCOSMenu("cos"); $mm{menuitems}{$i} = { "prompt" => "Default Class of Service Configuration:", "submenu" => $submenu, }; $i++; } $i = &preinstall::mainMenuExtensions(\%mm, $i); # $mm{menuitems}{r} = { # "prompt" => "Start servers after configuration", # "callback" => \&toggleYN, # "var" => \$config{STARTSERVERS}, # "arg" => "STARTSERVERS" # }; if ($config{EXPANDMENU} eq "yes") { $mm{menuitems}{c} = { "prompt" => "Collapse menu", "callback" => \&toggleYN, "arg" => "EXPANDMENU" }; } else { $mm{menuitems}{x} = { "prompt" => "Expand menu", "callback" => \&toggleYN, "arg" => "EXPANDMENU" }; } # Allow save of even incomplete config $mm{menuitems}{s} = { "prompt" => "Save config to file", "callback" => \&saveConfig, }; if (checkMenuConfig(\%mm)) { $mm{promptitem} = { "selector" => "a", "prompt" => "*** CONFIGURATION COMPLETE - press 'a' to apply\nSelect from menu, or press 'a' to apply config", "callback" => \&applyConfig, }; } else { $mm{promptitem} = { "selector" => "qqazyre", "prompt" => "Address unconfigured (**) items ", "callback" => \&applyConfig, }; if (!ldapIsAvailable() && $ldapConfigured) { $mm{promptitem}{prompt} .= "or correct ldap configuration "; } if ($config{LDAPHOST} ne $config{HOSTNAME} && !ldapIsAvailable() && isInstalled("zimbra-ldap")) { $mm{promptitem}{prompt} .= "and enable ldap replication on ldap master " if (checkLdapReplicationEnabled($config{zimbra_ldap_userdn},$config{LDAPADMINPASS})); } } return \%mm; } sub checkMenuConfig { my $items = shift; my $needldapverified = 0; foreach my $i (sort menuSort keys %{$$items{menuitems}}) { my $v; my $ind = " "; if (defined $$items{menuitems}{$i}{var}) { $v = ${$$items{menuitems}{$i}{var}}; if ($v eq "" || $v eq "none" || $v eq "UNSET" || $v eq "Not Verified") { return 0; } foreach my $var (qw(LDAPHOST LDAPPORT)) { if ($$items{menuitems}{$i}{var} == \$config{$var}) { $needldapverified = 1; } } } if (defined ($$items{menuitems}{$i}{submenu}) ) { if (!checkMenuConfig($$items{menuitems}{$i}{submenu})) { return 0; } } } if ($needldapverified) { return 1 if ($config{LDAPHOST} eq $config{HOSTNAME} && !$ldapConfigured); return 0 if (!ldapIsAvailable()); } if (defined($installedPackages{"zimbra-store"}) && $config{SERVICEWEBAPP} eq "no" && $config{UIWEBAPPS} eq "no" ) { $config{SERVICEWEBAPP}="UNSET"; $config{UIWEBAPPS}="UNSET"; return 0; } return 1; } sub ldapIsAvailable { my $failedcheck=0; if (($config{LDAPHOST} eq $config{HOSTNAME}) && !$ldapConfigured) { detail("This is the ldap master and ldap hasn't been configured yet."); return 0; } # check zimbra ldap admin user binding to the master if ($config{LDAPADMINPASS} eq "" || $config{LDAPPORT} eq "" || $config{LDAPHOST} eq "") { detail ( "ldap configuration not complete\n" ); return 0; } if (checkLdapBind($config{zimbra_ldap_userdn},$config{LDAPADMINPASS})) { detail ("Couldn't bind to $config{LDAPHOST} as $config{zimbra_ldap_userdn}\n"); $config{LDAPADMINPASSSET} = "Not Verified"; $failedcheck++; } else { detail ("Verified $config{zimbra_ldap_userdn} on $config{LDAPHOST}.\n"); $config{LDAPADMINPASSSET} = "set"; setLocalConfig ("zimbra_ldap_password", $config{LDAPADMINPASS}); setLdapDefaults() if ($config{LDAPHOST} ne $config{HOSTNAME}); } # check zmbes searcher binding to the master if ($config{LDAPHOST} eq $config{HOSTNAME}) { if ($config{ldap_bes_searcher_password} eq "") { detail ("BES searcher configuration not complete\n"); $failedcheck++; } my $binduser = "uid=zmbes-searcher,cn=appaccts,$config{ldap_dit_base_dn_config}"; if (checkLdapBind($binduser,$config{ldap_bes_searcher_password})) { detail ("Couldn't bind to $config{LDAPHOST} as $binduser\n"); $config{LDAPBESSEARCHSET} = "Not Verified"; $failedcheck++; } else { detail ("Verified $binduser on $config{LDAPHOST}.\n"); $config{LDAPBESSEARCHSET} = "set"; } } # check nginx user binding to the master if (isInstalled("zimbra-proxy")) { if ($config{ldap_nginx_password} eq "") { detail ("nginx configuration not complete\n"); $failedcheck++; } my $binduser = "uid=zmnginx,cn=appaccts,$config{ldap_dit_base_dn_config}"; if (checkLdapBind($binduser,$config{ldap_nginx_password})) { detail ("Couldn't bind to $config{LDAPHOST} as $binduser\n"); $config{LDAPNGINXPASSSET} = "Not Verified"; $failedcheck++; } else { detail ("Verified $binduser on $config{LDAPHOST}.\n"); $config{LDAPNGINXPASSSET} = "set"; } } # check postfix and amavis user binding to the master if (isInstalled("zimbra-mta")) { if ($config{LDAPPOSTPASS} eq "" || $config{LDAPAMAVISPASS} eq "") { detail ("mta configuration not complete\n"); $failedcheck++; } my $binduser = "uid=zmpostfix,cn=appaccts,$config{ldap_dit_base_dn_config}"; if (checkLdapBind($binduser,$config{LDAPPOSTPASS})) { detail ("Couldn't bind to $config{LDAPHOST} as $binduser\n"); $config{LDAPPOSTPASSSET} = "Not Verified"; detail ("Setting LDAPPOSTPASSSET to $config{LDAPPOSTPASSSET}") if $debug; $failedcheck++; } else { detail ("Verified $binduser on $config{LDAPHOST}.\n"); $config{LDAPPOSTPASSSET} = "set"; } my $binduser = "uid=zmamavis,cn=appaccts,$config{ldap_dit_base_dn_config}"; if (checkLdapBind($binduser,$config{LDAPAMAVISPASS})) { detail ("Couldn't bind to $config{LDAPHOST} as $binduser\n"); $config{LDAPAMAVISPASSSET} = "Not Verified"; detail ("Setting LDAPAMAVISPASSSET to $config{LDAPAMAVISPASSSET}") if $debug; $failedcheck++; } else { detail ("Verified $binduser on $config{LDAPHOST}.\n"); $config{LDAPAMAVISPASSSET}="set"; } } # check replication user binding to master if (isInstalled("zimbra-ldap") && $config{LDAPHOST} ne $config{HOSTNAME}) { if ($config{LDAPREPPASS} eq "") { detail ("ldap configuration not complete. Ldap Replication password is not set.\n"); $failedcheck++; } my $binduser = "uid=zmreplica,cn=admins,$config{ldap_dit_base_dn_config}"; if (checkLdapBind($binduser,$config{LDAPREPPASS})) { detail ("Couldn't bind to $config{LDAPHOST} as $binduser\n"); $config{LDAPREPPASSSET}="Not Verified"; detail ("Setting LDAPREPPASSSET to $config{LDAPREPPASSSET}") if $debug; $failedcheck++; } else { detail ("Verified $binduser on $config{LDAPHOST}.\n"); $config{LDAPREPPASSSET}="set"; } if (checkLdapReplicationEnabled($config{zimbra_ldap_userdn},$config{LDAPADMINPASS})) { detail ("ldap configuration not complete. Unable to verify ldap replication is enabled on $config{LDAPHOST}\n"); $failedcheck++; } else { detail ("ldap replication ability verified\n"); } } return ($failedcheck > 0) ? 0 : 1; } sub checkLdapBind() { my ($binduser,$bindpass) = @_; detail( "Checking ldap on $config{LDAPHOST}:$config{LDAPPORT}"); my $ldap; my $ldap_secure = (($config{LDAPPORT} == "636") ? "s" : ""); my $ldap_url = "ldap${ldap_secure}://$config{LDAPHOST}:$config{LDAPPORT}"; unless($ldap = Net::LDAP->new($ldap_url)) { detail("failed: Unable to contact ldap at $ldap_url: $!"); return 1; } if ($ldap_secure ne "s" && $config{zimbra_require_interprocess_security}) { $starttls = 1; my $result = $ldap->start_tls(verify=>'none'); if ($result->code()) { detail("Unable to startTLS: $!\n"); detail("Disabling the requirement for interprocess security.\n"); $config{zimbra_require_interprocess_security} = 0; $config{ZIMBRA_REQ_SECURITY}="no"; $starttls = 0; } } else { $starttls = 0; } my $result = $ldap->bind($binduser, password => $bindpass); if ($result->code()) { detail ("Unable to bind to $ldap_url with user $binduser: $!"); return 1; } else { $ldap->unbind; detail ("Verified ldap running at $ldap_url\n"); if ($newinstall) { setLocalConfig("ldap_url", $ldap_url); setLocalConfig("ldap_starttls_supported", $starttls); setLocalConfig("zimbra_require_interprocess_security", $config{zimbra_require_interprocess_security}); } setLocalConfig("ssl_allow_untrusted_certs", "true") if ($newinstall); return 0; } } sub checkLdapReplicationEnabled() { my ($binduser,$bindpass) = @_; detail( "Checking ldap replication is enabled on $config{LDAPHOST}:$config{LDAPPORT}"); my $ldap; my $ldap_secure = (($config{LDAPPORT} == "636") ? "s" : ""); my $ldap_url = "ldap${ldap_secure}://$config{LDAPHOST}:$config{LDAPPORT}"; unless($ldap = Net::LDAP->new($ldap_url)) { detail("failed: Unable to contact ldap at $ldap_url: $!"); return 1; } if ($ldap_secure ne "s" && $starttls) { my $result = $ldap->start_tls(verify=>'none'); if ($result->code()) { detail("Unable to startTLS: $!\n"); detail("Disabling the requirement for interprocess security.\n"); $config{zimbra_require_interprocess_security} = 0; $config{ZIMBRA_REQ_SECURITY}="no"; $starttls = 0; } } my $result = $ldap->bind($binduser, password => $bindpass); if ($result->code()) { detail ("Unable to bind to $ldap_url with user $binduser: $!"); return 1; } else { my $result = $ldap->search(base=>"cn=accesslog", scope=>"base", filter=>"cn=accesslog", attrs=>['cn']); if ($result->code()) { detail("Unable to find accesslog database on master.\n"); if ($config{LDAPREPLICATIONTYPE} eq "replica") { detail("Please run zmldapenablereplica on the master.\n"); } elsif ($config{LDAPREPLICATIONTYPE} eq "mmr") { detail("Please run zmldapenable-mmr on the master.\n"); } return 1; } else { detail("Verified ability to query accesslog on master.\n"); } } return 0; } sub runAsRoot { my $cmd = shift; if ($cmd =~ /ldappass/ || $cmd =~ /init/ || $cmd =~ /zmprov -r -m -l ca/) { # Suppress passwords in log file my $c = (split ' ', $cmd)[0]; detail ( "*** Running as root user: $c\n" ); } else { detail ( "*** Running as root user: $cmd\n" ); } my $rc; $rc = 0xffff & system("$cmd >> $logfile 2>&1"); return $rc; } sub runAsZimbra { my $cmd = shift; if ($cmd =~ /ldappass/ || $cmd =~ /init/ || $cmd =~ /zmprov -r -m -l ca/ || $cmd =~ /zmlicense/) { # Suppress passwords in log file my $c = (split ' ', $cmd)[0]; detail ( "*** Running as zimbra user: $c\n" ); } else { detail ( "*** Running as zimbra user: $cmd\n" ); } my $rc; $rc = 0xffff & system("$SU \"$cmd\" >> $logfile 2>&1"); return $rc; } sub runAsZimbraWithOutput { my $cmd = shift; if ($cmd =~ /ldappass/ || $cmd =~ /init/ || $cmd =~ /zmprov -r -m -l ca/) { # Suppress passwords in log file my $c = (split ' ', $cmd)[0]; detail ( "*** Running as zimbra user: $c\n" ); } else { detail ( "*** Running as zimbra user: $cmd\n" ); } system("$SU \"$cmd\""); my $exit_value = $? >> 8; my $signal_num = $? & 127; my $dumped_core = $? & 128; detail ("DEBUG: exit status from cmd was $exit_value") if $debug; return $exit_value; } sub getLocalConfig { my ($key,$force) = @_; return $main::loaded{lc}{$key} if (exists $main::loaded{lc}{$key} && !$force); detail ( "Getting local config $key" ); my $val = qx(/opt/zimbra/bin/zmlocalconfig -x -s -m nokey ${key} 2> /dev/null); chomp $val; detail ("DEBUG: LC Loaded $key=$val") if $debug; $main::loaded{lc}{$key} = $val; return $val; } sub getLocalConfigRaw { my ($key,$force) = @_; return $main::loaded{lc}{$key} if (exists $main::loaded{lc}{$key} && !$force); detail ( "Getting local config $key" ); my $val = qx(/opt/zimbra/bin/zmlocalconfig -s -m nokey ${key} 2> /dev/null); chomp $val; detail ("DEBUG: LC Loaded $key=$val") if $debug; $main::loaded{lc}{$key} = $val; return $val; } sub deleteLocalConfig { my $key = shift; detail ( "Deleting local config $key" ); my $rc = runAsZimbra("/opt/zimbra/bin/zmlocalconfig -u ${key} 2> /dev/null"); if ($rc == 0) { detail ("DEBUG: deleted localconfig key $key") if $debug; delete($main::loaded{lc}{$key}) if (exists $main::loaded{lc}{$key}); return 1; } else { detail ("DEBUG: failed to deleted localconfig key $key") if $debug; return undef } } sub setLocalConfig { my $key = shift; my $val = shift; if (exists $main::saved{lc}{$key} && $main::saved{lc}{$key} eq $val) { detail("Skipping update of unchanged value for $key=$val."); return; } detail ( "Setting local config $key to $val" ); $main::saved{lc}{$key} = $val; $main::loaded{lc}{$key} = $val; $val =~ s/\$/\\\$/g; runAsZimbra("/opt/zimbra/bin/zmlocalconfig -f -e ${key}=\'${val}\' 2> /dev/null"); } sub updateKeyValue { my ($sec,$key,$val,$sub) = @_; if ($key =~ /^\+(.*)/) { # TODO remove duplicates $main::loaded{$sec}{$sub}{$1}="$main::loaded{$sec}{$sub}{$1}\n$val"; $main::saved{$sec}{$sub}{$1}=$main::loaded{$sec}{$sub}{$1}; } elsif ($key =~ /^-(.*)/) { if (exists $main::loaded{$sec}{$sub}{$1}) { my %tmp = map { $_ => 1 } split(/\n/, $main::loaded{$sec}{$sub}{$1}); delete $tmp{$val}; $main::loaded{$sec}{$sub}{$1}=join "\n", keys %tmp; $main::saved{$sec}{$sub}{$1}=$main::loaded{$sec}{$sub}{$1}; } } else { $main::loaded{$sec}{$sub}{$key}=$val; $main::saved{$sec}{$sub}{$key}=$val; } } sub ifKeyValueEquate { my ($sec,$key,$val,$sub) = @_; $key=$1 if ($key =~ /^[+|-](.*)/); detail("Checking to see if $key=$val has changed for $sec $sub\n") if $debug; if (exists $main::saved{$sec}{$sub}{$key} && $main::saved{$sec}{$sub}{$key} eq $val) { #detail("DEBUG: \"$main::saved{$sec}{$sub}{$key}\" eq \"$val\"\n") if $debug; return 1; } else { #detail("DEBUG: \"$main::saved{$sec}{$sub}{$key}\" ne \"$val\"\n") if $debug; return 0; } } # # setLdapGlobalConfig(key, val [, key, val ...]) # sub setLdapGlobalConfig { my $zmprov_arg_str; my $sec="gcf"; while (@_){ my $key = shift; my $val = shift; detail("entering function: $sec $key=$val\n"); if (ifKeyValueEquate($sec,$key,$val,$sec)) { detail("Skipping update of unchanged value for $key=$val."); } else { detail("Updating cached global config attribute $key=$val"); updateKeyValue($sec,$key,$val,$sec); $zmprov_arg_str .= " $key \'$val\'"; } } if ($zmprov_arg_str) { my $rc = runAsZimbra("$ZMPROV mcf $zmprov_arg_str"); return $rc; } } # # setLdapServerConfig([server,] key, val [, key, val ...]) # sub setLdapServerConfig { my $zmprov_arg_str; my $sec="gs"; my $server; if (($#_ % 2) == 0) { $server = shift; } else { $server = $config{HOSTNAME}; } return undef if ($server eq ""); while (@_) { my $key = shift; my $val = shift; if (ifKeyValueEquate($sec,$key,$val,$server)) { detail("Skipping update of unchanged value for $key=$val."); } else { detail("Updating cached config attribute for Server $server: $key=$val"); updateKeyValue($sec,$key,$val,$server); $zmprov_arg_str .= " $key \'$val\'"; } } if ($zmprov_arg_str) { my $rc = runAsZimbra("$ZMPROV ms $server $zmprov_arg_str"); return $rc; } } # # setLdapDomainConfig([domain,] key, val [, key, val ...]) # sub setLdapDomainConfig { my $zmprov_arg_str; my $domain; if (($#_ % 2) == 0) { $domain = shift; } else { $domain = getLdapConfigValue("zimbraDefaultDomainName"); } return undef if ($domain eq ""); my $sec="domain"; while (@_) { my $key = shift; my $val = shift; if (ifKeyValueEquate($sec,$key,$val,$domain)) { detail("Skipping update of unchanged value for $key=$val."); } else { detail("Updating cached config attribute for Domain $domain: $key=$val"); updateKeyValue($sec,$key,$val,$domain); $zmprov_arg_str .= " $key \'$val\'"; } } if ($zmprov_arg_str) { my $rc = runAsZimbra("$ZMPROV md $domain $zmprov_arg_str"); return $rc; } } # # setLdapCOSConfig([cos,] key, val [, key, val ...]) # sub setLdapCOSConfig { my $zmprov_arg_str; my $cos; if (($#_ % 2) == 0) { $cos = shift; } else { $cos = 'default'; } my $sec="gc"; while (@_) { my $key = shift; my $val = shift; if (ifKeyValueEquate($sec,$key,$val,$cos)) { detail("Skipping update of unchanged value for $key=$val."); } else { detail("Updating cached config attribute for COS $cos: $key=$val"); updateKeyValue($sec,$key,$val,$cos); $zmprov_arg_str .= " $key \'$val\'"; } } if ($zmprov_arg_str) { my $rc = runAsZimbra("$ZMPROV mc $cos $zmprov_arg_str"); return $rc; } } # # setLdapAccountConfig(acct, key, val [, key, val ...]) # sub setLdapAccountConfig { my $zmprov_arg_str; my $acct; if (($#_ % 2) == 0) { $acct = shift; } return undef if ($acct eq ""); my $sec="acct"; while (@_) { my $key = shift; my $val = shift; if (ifKeyValueEquate($sec,$key,$val,$acct)) { detail("Skipping update of unchanged value for $key=$val."); } else { detail("Updating cached config attribute for Account $acct: $key=$val"); updateKeyValue($sec,$key,$val,$acct); $zmprov_arg_str .= " $key \'$val\'"; } } if ($zmprov_arg_str) { my $rc = runAsZimbra("$ZMPROV ma $acct $zmprov_arg_str"); return $rc; } } sub configLCValues { if ($configStatus{configLCValues} eq "CONFIGURED") { configLog("configLCValues"); return 0; } progress ("Setting local config values..."); setLocalConfig ("zimbra_server_hostname", lc($config{HOSTNAME})); setLocalConfig ("zimbra_require_interprocess_security", $config{zimbra_require_interprocess_security}); if($newinstall) { if ($config{LDAPPORT} == 636) { setLocalConfig ("ldap_master_url", "ldaps://$config{LDAPHOST}:$config{LDAPPORT}"); setLocalConfig ("ldap_url", "ldaps://$config{LDAPHOST}:$config{LDAPPORT}"); setLocalConfig ("ldap_starttls_supported", 0); } else { setLocalConfig ("ldap_master_url", "ldap://$config{LDAPHOST}:$config{LDAPPORT}"); if ($config{ldap_url} eq "") { setLocalConfig ("ldap_url", "ldap://$config{LDAPHOST}:$config{LDAPPORT}"); if ($config{zimbra_require_interprocess_security}) { setLocalConfig ("ldap_starttls_supported", 1); } else { setLocalConfig ("ldap_starttls_supported", 0); } } else { setLocalConfig ("ldap_url", "$config{ldap_url}"); if ($config{ldap_url} !~ /^ldaps/i && $config{zimbra_require_interprocess_security}) { setLocalConfig ("ldap_starttls_supported", 1); } else { setLocalConfig ("ldap_starttls_supported", 0); } } } } # set default zmprov bahaviour if (isEnabled("zimbra-store") && isStoreServiceNode()) { setLocalConfig ("zimbra_zmprov_default_to_ldap", "false"); } else { setLocalConfig ("zimbra_zmprov_default_to_ldap", "true"); } setLocalConfig ("ldap_port", "$config{LDAPPORT}"); setLocalConfig ("ldap_host", "$config{LDAPHOST}"); my $uid = qx(id -u zimbra); chomp $uid; my $gid = qx(id -g zimbra); chomp $gid; setLocalConfig ("zimbra_uid", $uid); setLocalConfig ("zimbra_gid", $gid); setLocalConfig ("zimbra_user", "zimbra"); if (defined $config{AVUSER}) { setLocalConfig ("av_notify_user", $config{AVUSER}) } if (defined $config{AVDOMAIN}) { setLocalConfig ("av_notify_domain", $config{AVDOMAIN}) } setLocalConfig ("ssl_allow_untrusted_certs", "true") if ($newinstall); setLocalConfig ("ssl_allow_mismatched_certs", "true") if ($newinstall); setLocalConfig ("ssl_default_digest", $config{ssl_default_digest}); setLocalConfig ("mailboxd_java_heap_size", $config{MAILBOXDMEMORY}); setLocalConfig ("mailboxd_directory", $config{mailboxd_directory}); setLocalConfig ("mailboxd_keystore", $config{mailboxd_keystore}); setLocalConfig ("mailboxd_server", $config{mailboxd_server}); setLocalConfig ("mailboxd_truststore", "$config{mailboxd_truststore}"); setLocalConfig ("mailboxd_truststore_password", "$config{mailboxd_truststore_password}"); setLocalConfig ("mailboxd_keystore_password", "$config{mailboxd_keystore_password}"); setLocalConfig ("zimbra_ldap_userdn", "$config{zimbra_ldap_userdn}"); setLocalConfig ("ldap_dit_base_dn_config", "$config{ldap_dit_base_dn_config}") if ($config{ldap_dit_base_dn_config} ne "cn=zimbra"); configLog ("configLCValues"); progress ("done.\n"); } sub configCASetup { if ($configStatus{configCASetup} eq "CONFIGURED" && -d "/opt/zimbra/ssl/zimbra/ca" ) { configLog("configCASetup"); return 0; } if ($config{LDAPHOST} ne $config{HOSTNAME}) { # fetch it from ldap if ldap has been configed progress("Updating ldap_root_password and zimbra_ldap_password..."); setLocalConfig ("ldap_root_password", $config{LDAPROOTPASS}); setLocalConfig ("zimbra_ldap_password", $config{LDAPADMINPASS}); progress ( "done.\n" ); } progress ( "Setting up CA..." ); if (! $newinstall) { if (-f "/opt/zimbra/conf/ca/ca.pem") { my $rc = runAsRoot("/opt/zimbra/common/bin/openssl verify -purpose sslserver -CAfile /opt/zimbra/conf/ca/ca.pem /opt/zimbra/conf/ca/ca.pem | egrep \"^error 10\""); $needNewCert = "-new" if ($rc == 0); } } # regenerate the certificate authority if this is the ldap master and # either the ca is expired from the test above or the ca directory doesn't exist. my $needNewCA; if (isLdapMaster()) { $needNewCA = "-new" if (! -d "/opt/zimbra/ssl/zimbra/ca" || $needNewCert eq "-new"); } # we are going to download a new CA or otherwise create one so we need to regenerate the self signed cert. $needNewCert = "-new" if (! -d "/opt/zimbra/ssl/zimbra/ca"); my $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createca $needNewCA"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } progress ( "Deploying CA to /opt/zimbra/conf/ca ..." ); my $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr deployca -localonly"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } configLog("configCASetup"); } sub configSetupLdap { if ($configStatus{configSetupLdap} eq "CONFIGURED") { detail("ldap already configured bypassing configuration\n"); configLog("configSetupLdap"); return 0; } if (!$ldapConfigured && isEnabled("zimbra-ldap") && ! -f "/opt/zimbra/.enable_replica" && $newinstall && ($config{LDAPHOST} eq $config{HOSTNAME})) { progress ( "Initializing ldap..." ) ; if (my $rc = runAsZimbra("/opt/zimbra/libexec/zmldapinit \'$config{LDAPROOTPASS}\' \'$config{LDAPADMINPASS}\'")) { progress ( "failed. ($rc)\n" ); failConfig(); } else { progress ( "done.\n" ); if ($ldapRepChanged == 1) { progress ( "Setting replication password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -l \'$config{LDAPREPPASS}\'"); progress ( "done.\n" ); } if ($ldapPostChanged == 1) { progress ( "Setting Postfix password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -p \'$config{LDAPPOSTPASS}\'"); progress ( "done.\n" ); } if ($ldapAmavisChanged == 1) { progress ( "Setting amavis password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -a \'$config{LDAPAMAVISPASS}\'"); progress ( "done.\n" ); } if ($ldapNginxChanged == 1) { progress ( "Setting nginx password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -n \'$config{ldap_nginx_password}\'"); progress ( "done.\n" ); } if ($ldapBesSearcherChanged == 1) { progress ( "Setting BES searcher password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -b \'$config{ldap_bes_searcher_password}\'"); progress ( "done.\n" ); } } if ($config{FORCEREPLICATION} eq "yes") { my $rc = runAsZimbra ("/opt/zimbra/libexec/zmldapenablereplica"); my $file="/opt/zimbra/.enable_replica"; open(ER,">>$file"); close ER; } if (isNetwork()) { setLdapGlobalConfig("zimbraRedoLogDeleteOnRollover", "FALSE"); } } elsif (isEnabled("zimbra-ldap")) { my $rc; if ($newinstall) { $rc = runAsZimbra ("/opt/zimbra/libexec/zmldapapplyldif"); } if (!$newinstall) { $rc = runAsZimbra ("/opt/zimbra/libexec/zmldapupdateldif"); } # enable replica for both new and upgrade installs if we are adding ldap if ($config{LDAPHOST} ne $config{HOSTNAME} || -f "/opt/zimbra/.enable_replica") { progress("Updating ldap_root_password and zimbra_ldap_password..."); setLocalConfig ("ldap_root_password", $config{LDAPROOTPASS}); setLocalConfig ("zimbra_ldap_password", $config{LDAPADMINPASS}); setLocalConfig ("ldap_replication_password", "$config{LDAPREPPASS}"); if($newinstall && $config{LDAPREPLICATIONTYPE} eq "mmr") { if ($ldapPostChanged == 1) { progress ( "Setting Postfix password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -p \'$config{LDAPPOSTPASS}\'"); progress ( "done.\n" ); } if ($ldapAmavisChanged == 1) { progress ( "Setting amavis password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -a \'$config{LDAPAMAVISPASS}\'"); progress ( "done.\n" ); } if ($ldapNginxChanged == 1) { progress ( "Setting nginx password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -n \'$config{ldap_nginx_password}\'"); progress ( "done.\n" ); } } progress("done.\n"); progress ( "Enabling ldap replication..." ); if ( ! -f "/opt/zimbra/.enable_replica" ) { if ($newinstall && $config{LDAPREPLICATIONTYPE} eq "mmr") { setLocalConfig ("ldap_is_master", "true"); my $ldapMasterUrl = getLocalConfig ("ldap_master_url"); my $proto = "ldap"; if ($config{LDAPPORT} == "636") { $proto="ldaps"; } setLocalConfig("ldap_url", "$proto://$config{HOSTNAME}:$config{LDAPPORT} $ldapMasterUrl"); if ($ldapMasterUrl !~ /\/$/) { $ldapMasterUrl=$ldapMasterUrl."/"; } runAsZimbra ("/opt/zimbra/bin/ldap start"); $rc = runAsZimbra ("/opt/zimbra/libexec/zmldapenable-mmr -s $config{LDAPSERVERID} -m $ldapMasterUrl"); } else { $rc = runAsZimbra ("/opt/zimbra/libexec/zmldapenablereplica"); } my $file="/opt/zimbra/.enable_replica"; open(ER,">>$file"); close ER; } if ($rc == 0) { if (!isEnabled("zimbra-store")) { $config{DOCREATEADMIN} = "no"; } $config{DOCREATEDOMAIN} = "no"; progress ( "done.\n" ); progress("Stopping ldap..."); runAsZimbra ("/opt/zimbra/bin/ldap stop"); progress("done.\n"); startLdap(); } else { progress ("failed.\n"); progress ("You will have to correct the problem and manually enable replication.\n"); progress ("Disabling ldap on $config{HOSTNAME}..."); my $rc = setLdapServerConfig("-zimbraServiceEnabled", "ldap"); progress(($rc == 0) ? "done.\n" : "failed.\n"); progress("Stopping ldap..."); runAsZimbra ("/opt/zimbra/bin/ldap stop"); progress("done.\n"); } } # zmldappasswd starts ldap and re-applies the ldif if ($ldapRootPassChanged || $ldapAdminPassChanged || $ldapRepChanged || $ldapPostChanged || $ldapAmavisChanged || $ldapNginxChanged || $ldapBesSearcherChanged) { if ($ldapRootPassChanged) { progress ( "Setting ldap root password..." ); runAsZimbra ("/opt/zimbra/bin/zmldappasswd -r $config{LDAPROOTPASS}"); progress ( "done.\n" ); } if ($ldapAdminPassChanged) { progress ( "Setting ldap admin password..." ); if ($config{LDAPHOST} eq $config{HOSTNAME} ) { runAsZimbra ("/opt/zimbra/bin/zmldappasswd $config{LDAPADMINPASS}"); } else { setLocalConfig ("zimbra_ldap_password", "$config{LDAPADMINPASS}"); } progress ( "done.\n" ); } if ($ldapRepChanged == 1) { progress ( "Setting replication password..." ); if ($config{LDAPHOST} eq $config{HOSTNAME} ) { runAsZimbra ("/opt/zimbra/bin/zmldappasswd -l $config{LDAPREPPASS}"); } else { setLocalConfig ("ldap_replication_password", "$config{LDAPREPPASS}"); } progress ( "done.\n" ); } if ($ldapPostChanged == 1) { progress ( "Setting Postfix password..." ); if ($config{LDAPHOST} eq $config{HOSTNAME} ) { runAsZimbra ("/opt/zimbra/bin/zmldappasswd -p $config{LDAPPOSTPASS}"); } else { setLocalConfig ("ldap_postfix_password", "$config{LDAPPOSTPASS}"); } progress ( "done.\n" ); } if ($ldapAmavisChanged == 1) { progress ( "Setting amavis password..." ); if ($config{LDAPHOST} eq $config{HOSTNAME} ) { runAsZimbra ("/opt/zimbra/bin/zmldappasswd -a $config{LDAPAMAVISPASS}"); } else { setLocalConfig ("ldap_amavis_password", "$config{LDAPAMAVISPASS}"); } progress ( "done.\n" ); } if ($ldapNginxChanged == 1) { progress ( "Setting nginx password..." ); if ($config{LDAPHOST} eq $config{HOSTNAME} ) { runAsZimbra ("/opt/zimbra/bin/zmldappasswd -n $config{ldap_nginx_password}"); } else { setLocalConfig ("ldap_nginx_password", "$config{ldap_nginx_password}"); } progress ( "done.\n" ); } if ($ldapBesSearcherChanged == 1) { progress ( "Setting BES Searcher password..." ); if ($config{LDAPHOST} eq $config{HOSTNAME} ) { runAsZimbra ("/opt/zimbra/bin/zmldappasswd -b $config{ldap_bes_searcher_password}"); } else { setLocalConfig ("ldap_bes_searcher_password", "$config{ldap_bes_searcher_password}"); } progress ( "done.\n" ); } } else { progress("Stopping ldap..."); runAsZimbra ("/opt/zimbra/bin/ldap stop"); progress("done.\n"); startLdap(); } } else { detail("Updating ldap user passwords\n"); setLocalConfig ("ldap_root_password", $config{LDAPROOTPASS}); setLocalConfig ("zimbra_ldap_password", $config{LDAPADMINPASS}); setLocalConfig ("ldap_replication_password", "$config{LDAPREPPASS}"); setLocalConfig ("ldap_postfix_password", "$config{LDAPPOSTPASS}"); setLocalConfig ("ldap_amavis_password", "$config{LDAPAMAVISPASS}"); setLocalConfig ("ldap_nginx_password", "$config{ldap_nginx_password}"); setLocalConfig ("ldap_bes_searcher_password", "$config{ldap_bes_searcher_password}"); } configLog("configSetupLdap"); return 0; } sub configLDAPSchemaVersion { return if ($haveSetLdapSchemaVersion); if (isEnabled("zimbra-ldap")) { progress ("Updating zimbraLDAPSchemaVersion to version '$ldapSchemaVersion'\n"); setLdapGlobalConfig('zimbraLDAPSchemaVersion', $ldapSchemaVersion); $haveSetLdapSchemaVersion = 1; } } sub configSetupEphemeralBackend { if (exists($config{EphemeralBackendURL})) { setLdapGlobalConfig("zimbraEphemeralBackendURL", "$config{EphemeralBackendURL}") } configLog("configSetupEphemeralBackend"); return 0; } sub configSaveCA { if ($configStatus{configSaveCA} eq "CONFIGURED") { configLog("configSaveCA"); return 0; } progress ( "Saving CA in ldap..." ); my $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr deployca"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } configLog("configSaveCA"); } sub configCreateCert { if ($configStatus{configCreateCert} eq "CONFIGURED" && -d "/opt/zimbra/ssl/zimbra/server") { configLog("configCreateCert"); return 0; } if (!$newinstall) { my $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr verifycrt comm > /dev/null 2>&1"); if ($rc != 0) { $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr verifycrt self > /dev/null 2>&1"); if ($rc != 0) { progress("Warning: No valid SSL certificates were found.\n"); progress("New self-signed certificates will be generated and installed.\n"); $needNewCert = "-new" if ($rc != 0); $ssl_cert_type="self"; } } else { $ssl_cert_type="comm"; $needNewCert=""; } } my $rc; if (isInstalled("zimbra-imapd")) { if ( !-f "$config{imapd_keystore}" && !-f "/opt/zimbra/conf/server.crt" ) { progress ( "Creating SSL zimbra-imapd certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } elsif ( $needNewCert ne "" && $ssl_cert_type eq "self") { progress ( "Creating new zimbra-imapd SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } } if (isInstalled("zimbra-store")) { if ( !-f "$config{mailboxd_keystore}" && !-f "/opt/zimbra/ssl/zimbra/server/server.crt" ) { if (!-d "$config{mailboxd_directory}") { qx(mkdir -p $config{mailboxd_directory}/etc); qx(chown -R zimbra:zimbra $config{mailboxd_directory}); qx(chmod 744 $config{mailboxd_directory}/etc); } progress ( "Creating SSL zimbra-store certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } elsif ( $needNewCert ne "" && $ssl_cert_type eq "self") { progress ( "Creating new zimbra-store SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } } if (isInstalled("zimbra-ldap")) { if ( !-f "/opt/zimbra/conf/slapd.crt" && !-f "/opt/zimbra/ssl/zimbra/server/server.crt") { progress ( "Creating zimbra-ldap SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } elsif ( $needNewCert ne "" && $ssl_cert_type eq "self") { progress ( "Creating new zimbra-ldap SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } } if (isInstalled("zimbra-mta")) { if ( !-f "/opt/zimbra/conf/smtpd.crt" && !-f "/opt/zimbra/ssl/zimbra/server/server.crt") { progress ( "Creating zimbra-mta SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } elsif ( $needNewCert ne "" && $ssl_cert_type eq "self") { progress ( "Creating new zimbra-mta SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } } if (isInstalled("zimbra-proxy")) { if ( !-f "/opt/zimbra/conf/nginx.crt" && !-f "/opt/zimbra/ssl/zimbra/server/server.crt") { progress ( "Creating zimbra-proxy SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } elsif ( $needNewCert ne "" && $ssl_cert_type eq "self") { progress ( "Creating new zimbra-proxy SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } } if (isInstalled("zimbra-onlyoffice")) { if ( !-f "/opt/zimbra/ssl/zimbra/server/server.crt") { progress ( "Creating SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } elsif ( $needNewCert ne "" && $ssl_cert_type eq "self") { progress ( "Creating new SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } } if (isInstalled("zimbra-license-daemon")) { if ( !-f "/opt/zimbra/ssl/zimbra/server/server.crt") { progress ( "Creating SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } elsif ( $needNewCert ne "" && $ssl_cert_type eq "self") { progress ( "Creating new SSL certificate..." ); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr createcrt $needNewCert"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } } } configLog("configCreateCert"); } sub configSaveCert { if ($configStatus{configSaveCert} eq "CONFIGURED") { configLog("configSaveCert"); return 0; } progress ( "Saving SSL Certificate in ldap..." ); my $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr savecrt $ssl_cert_type"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); } configLog("configSaveCert"); } sub configInstallCert { my $rc; if ($configStatus{configInstallCertStore} eq "CONFIGURED" && $needNewCert eq "") { configLog("configInstallCertStore"); } elsif (isInstalled("zimbra-store")) { if (! (-f "$config{mailboxd_keystore}") || $needNewCert ne "") { progress ("Installing mailboxd SSL certificates..."); detail("$config{mailboxd_keystore} didn't exist.") if (! -f "$config{mailboxd_keystore}"); detail("$needNewCert was ne \"\".") if ($needNewCert ne ""); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); configLog("configInstallCertStore"); } } else { configLog("configInstallCertStore"); } } if ($configStatus{configInstallCertImap} eq "CONFIGURED" && $needNewCert eq "") { configLog("configInstallCertImap"); } elsif (isInstalled("zimbra-imapd")) { if (! (-f "$config{imapd_keystore}") || $needNewCert ne "") { progress ("Installing imapd SSL certificates..."); detail("$config{imapd_keystore} didn't exist.") if (! -f "$config{imapd_keystore}"); detail("$needNewCert was ne \"\".") if ($needNewCert ne ""); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); configLog("configInstallCertImap"); } } else { configLog("configInstallCertImap"); } } if ($configStatus{configInstallCertMTA} eq "CONFIGURED" && $needNewCert eq "") { configLog("configInstallCertMTA"); } elsif (isInstalled("zimbra-mta")) { if (! (-f "/opt/zimbra/conf/smtpd.key" || -f "/opt/zimbra/conf/smtpd.crt" ) || $needNewCert ne "") { progress ("Installing MTA SSL certificates..."); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); configLog("configInstallCertMTA"); } } else { configLog("configInstallCertMTA"); } } if ($configStatus{configInstallCertLDAP} eq "CONFIGURED" && $needNewCert eq "") { configLog("configInstallCertLDAP"); } elsif (isInstalled("zimbra-ldap")) { if (! (-f "/opt/zimbra/conf/slapd.key" || -f "/opt/zimbra/conf/slapd.crt" ) || $needNewCert ne "") { progress ("Installing LDAP SSL certificate..."); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); stopLdap() if ($ldapConfigured); startLdap() if ($ldapConfigured); configLog("configInstallCertLDAP"); } } else { configLog("configInstallCertLDAP"); } } if ($configStatus{configInstallCertProxy} eq "CONFIGURED" && $needNewCert eq "") { configLog("configInstallCertProxy"); } elsif (isInstalled("zimbra-proxy")) { if (! (-f "/opt/zimbra/conf/nginx.key" || -f "/opt/zimbra/conf/nginx.crt") || $needNewCert ne "") { progress ("Installing Proxy SSL certificate..."); $rc = runAsZimbra("/opt/zimbra/bin/zmcertmgr deploycrt $ssl_cert_type"); if ($rc != 0) { progress ( "failed.\n" ); exit 1; } else { progress ( "done.\n" ); configLog("configInstallCertProxy"); } } else { configLog("configInstallCertProxy"); } } } sub configCreateServerEntry { if ($configStatus{configCreateServerEntry} eq "CONFIGURED") { configLog("configCreateServerEntry"); return 0; } progress ( "Creating server entry for $config{HOSTNAME}..." ); my $serverId = getLdapServerValue("zimbraId"); if ($serverId ne "") { progress("already exists.\n"); } else { my $rc = runAsZimbra("$ZMPROV cs $config{HOSTNAME}"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } progress ( "Setting Zimbra IP Mode..." ); my $rc = setLdapServerConfig("zimbraIPMode", $config{zimbraIPMode}); progress(($rc == 0) ? "done.\n" : "failed.\n"); my $rc = runAsZimbra("/opt/zimbra/libexec/zmiptool >/dev/null 2>/dev/null"); configLog("configCreateServerEntry"); } sub configSpellServer { if ($configStatus{configSpellServer} eq "CONFIGURED") { configLog("configSpellServer"); return 0; } if ($config{USESPELL} eq "yes") { progress ( "Setting spell check URL..." ); my $rc = setLdapServerConfig("zimbraSpellCheckURL", $config{SPELLURL}); progress(($rc == 0) ? "done.\n" : "failed.\n"); } configLog("configSpellServer"); } sub configConvertdURL { my $tmpval = getLdapConfigValue("zimbraConvertdURL"); if ( $tmpval eq "" ) { my $host; if (!$newinstall) { $host = $config{zimbra_server_hostname}; } else { $host = lc($config{HOSTNAME}); } progress("Setting convertd URL..."); my $rc = setLdapGlobalConfig("zimbraConvertdURL", "http://$host:7047/convert"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } } sub configSetStoreDefaults { if(isEnabled("zimbra-proxy") || $config{zimbraMailProxy} eq "TRUE" || $config{zimbraWebProxy} eq "TRUE") { $config{zimbraReverseProxyLookupTarget}="TRUE"; } # for mailstore split, set zimbraReverseProxyAvailableLookupTargets on service-only nodes if ($newinstall && isStoreServiceNode()) { my $adding=0; progress("Checking current setting of zimbraReverseProxyAvailableLookupTargets\n"); my $zrpALT = getLdapConfigValue("zimbraReverseProxyAvailableLookupTargets"); if ($zrpALT ne "") { $adding=1; } else { progress("Querying LDAP for other mailstores\n"); # query LDAP to see if there are other mailstores. If there are none, add this # new service node to zimbraReverseProxyAvailableLookupTargets. Otherwise do not my $count = countReverseProxyLookupTargets(); if (!defined($count) || $count == 0) { $adding=1; } } if ($adding) { progress("Adding $config{HOSTNAME} to zimbraReverseProxyAvailableLookupTargets\n"); setLdapGlobalConfig("+zimbraReverseProxyAvailableLookupTargets", $config{HOSTNAME}); } } $config{zimbraMtaAuthTarget}="TRUE"; if (!isStoreServiceNode()) { $config{zimbraMtaAuthTarget}="FALSE"; } if ($newinstall && isNetwork() && isStoreServiceNode()) { setLdapGlobalConfig("+zimbraReverseProxyUpstreamEwsServers", "$config{HOSTNAME}"); } if ($newinstall && isStoreWebNode()) { setLdapGlobalConfig("+zimbraReverseProxyUpstreamLoginServers", "$config{HOSTNAME}"); } setLdapServerConfig("zimbraReverseProxyLookupTarget", $config{zimbraReverseProxyLookupTarget}); setLdapServerConfig("zimbraMtaAuthTarget", $config{zimbraMtaAuthTarget}); my $upstream="-u"; if ($config{zimbra_require_interprocess_security}) { $upstream="-U"; } if ($newinstall && ($config{zimbraWebProxy} eq "TRUE" || $config{zimbraMailProxy} eq "TRUE")) { if ($config{zimbraMailProxy} eq "TRUE") { runAsZimbra("/opt/zimbra/libexec/zmproxyconfig $upstream -m -e -o ". "-i $config{IMAPPORT}:$config{IMAPPROXYPORT}:$config{IMAPSSLPORT}:$config{IMAPSSLPROXYPORT} ". "-p $config{POPPORT}:$config{POPPROXYPORT}:$config{POPSSLPORT}:$config{POPSSLPROXYPORT} -H $config{HOSTNAME}"); } if ($config{zimbraWebProxy} eq "TRUE") { runAsZimbra("/opt/zimbra/libexec/zmproxyconfig $upstream -w -e -o ". "-a $config{HTTPPORT}:$config{HTTPPROXYPORT}:$config{HTTPSPORT}:$config{HTTPSPROXYPORT} -H $config{HOSTNAME}"); } } if ($config{zimbraVersionCheckServer} eq "" && isStoreServiceNode()) { my $serverId = getLdapServerValue("zimbraId"); setLdapGlobalConfig("zimbraVersionCheckServer", $serverId); } # this should probably be in a global config section setLdapGlobalConfig("zimbraVersionCheckSendNotifications", $config{zimbraVersionCheckSendNotifications}); setLdapGlobalConfig("zimbraVersionCheckNotificationEmail", $config{zimbraVersionCheckNotificationEmail}); setLdapGlobalConfig("zimbraVersionCheckNotificationEmailFrom", $config{zimbraVersionCheckNotificationEmailFrom}); setLdapGlobalConfig("zimbraVersionCheckInterval", "0") if ($config{VERSIONUPDATECHECKS} eq "FALSE"); } sub isStoreWebNode { if ($installedWebapps{"zimbra"} eq "Enabled" || $installedWebapps{"zimbraAdmin"} eq "Enabled") { return 1; } else { return 0; } } sub isStoreServiceNode { if ($installedWebapps{"service"} eq "Enabled") { return 1; } else { return 0; } } sub configSetServicePorts { if ($configStatus{configSetServicePorts} eq "CONFIGURED") { configLog("configSetServicePorts"); return 0; } progress ( "Setting service ports on $config{HOSTNAME}..." ); if ($config{MAILPROXY} eq "FALSE") { if ($config{IMAPPORT} == 7143 && $config{IMAPPROXYPORT} == $config{IMAPPORT}) { $config{IMAPPROXYPORT} = 143; } if ($config{IMAPSSLPORT} == 7993 && $config{IMAPSSLPROXYPORT} == $config{IMAPSSLPORT}) { $config{IMAPSSLPROXYPORT} = 993; } if ($config{POPPORT} == 7110 && $config{POPPROXYPORT} == $config{POPPORT}) { $config{POPPROXYPORT} = 110; } if ($config{POPSSLPORT} == 7995 && $config{POPSSLPROXYPORT} == $config{POPSSLPORT}) { $config{POPSSLPORT} = 995; } } setLdapServerConfig($config{HOSTNAME}, "zimbraImapBindPort", $config{IMAPPORT}, "zimbraImapSSLBindPort", $config{IMAPSSLPORT}, "zimbraImapProxyBindPort", $config{IMAPPROXYPORT}, "zimbraImapSSLProxyBindPort", $config{IMAPSSLPROXYPORT} ); setLdapServerConfig($config{HOSTNAME}, "zimbraPop3BindPort", $config{POPPORT}, "zimbraPop3SSLBindPort", $config{POPSSLPORT}, "zimbraPop3ProxyBindPort", $config{POPPROXYPORT}, "zimbraPop3SSLProxyBindPort", $config{POPSSLPROXYPORT} ); if ($config{HTTPPROXY} eq "FALSE") { if ($config{HTTPPORT} == 8080 && $config{HTTPPROXYPORT} == $config{HTTPPORT}) { $config{HTTPPROXYPORT} = 80; } if ($config{HTTPSPORT} == 8443 && $config{HTTPSPROXYPORT} == $config{HTTPSPORT}){ $config{HTTPSPROXYPORT} = 443; } } setLdapServerConfig($config{HOSTNAME}, "zimbraMailPort", $config{HTTPPORT}, "zimbraMailSSLPort", $config{HTTPSPORT}, "zimbraMailProxyPort", $config{HTTPPROXYPORT}, "zimbraMailSSLProxyPort", $config{HTTPSPROXYPORT}, "zimbraMailMode", $config{MODE} ); setLocalConfig("zimbra_mail_service_port", $config{HTTPPORT}); progress ( "done.\n" ); configLog("configSetServicePorts"); } sub configSetKeyboardShortcutsPref { if ($configStatus{zimbraPrefUseKeyboardShortcuts} eq "CONFIGURED") { configLog("zimbraPrefUseKeyboardShortcuts"); return 0; } progress ( "Setting Keyboard Shortcut Preferences..."); my $rc = setLdapCOSConfig("zimbraPrefUseKeyboardShortcuts", $config{USEKBSHORTCUTS}); progress (($rc == 0) ? "done.\n" : "failed.\n"); configLog("zimbraPrefUseKeyboardShortcuts"); } sub configSetDNSCacheDefaults { if ($configStatus{zimbraDNSCache} eq "CONFIGURED") { configLog("zimbraDNSCache"); return 0; } progress ( "Setting Master DNS IP address(es)..."); my @IPs = split (' ', $config{zimbraDNSMasterIP}); my $rc; foreach my $ip (@IPs) { chomp ($ip); $ip =~s/"//g; $ip =~s/'//g; $rc=main::runAsZimbra("$ZMPROV ms $config{HOSTNAME} +zimbraDNSMasterIP $ip"); } progress(($rc == 0) ? "done.\n" : "failed.\n"); progress( "Setting DNS cache tcp lookup preference..."); $rc=main::runAsZimbra("$ZMPROV ms $config{HOSTNAME} zimbraDNSUseTCP $config{zimbraDNSUseTCP}"); progress(($rc == 0) ? "done.\n" : "failed.\n"); progress( "Setting DNS cache udp lookup preference..."); $rc=main::runAsZimbra("$ZMPROV ms $config{HOSTNAME} zimbraDNSUseUDP $config{zimbraDNSUseUDP}"); progress(($rc == 0) ? "done.\n" : "failed.\n"); progress( "Setting DNS tcp upstream preference..."); $rc=main::runAsZimbra("$ZMPROV ms $config{HOSTNAME} zimbraDNSTCPUpstream $config{zimbraDNSTCPUpstream}"); progress(($rc == 0) ? "done.\n" : "failed.\n"); configLog("zimbraDNSCache"); } sub configSetTimeZonePref { if ($configStatus{zimbraPrefTimeZoneId} eq "CONFIGURED") { configLog("zimbraPrefTimeZoneId"); return 0; } if($config{LDAPHOST} eq $config{HOSTNAME}) { progress ( "Setting TimeZone Preference..."); my $rc = setLdapCOSConfig("zimbraPrefTimeZoneId", $config{zimbraPrefTimeZoneId}); progress (($rc == 0) ? "done.\n" : "failed.\n"); } configLog("zimbraPrefTimeZoneId"); } sub configSetCEFeatures { foreach my $feature (qw(Tasks Briefcases)) { my $key = "zimbraFeature${feature}Enabled"; my $val = ($config{$key} eq "Enabled" ? "TRUE" : "FALSE"); if ($configStatus{$key} eq "CONFIGURED") { configLog($key); next; } progress ( "Setting $key=$val..."); my $rc = setLdapCOSConfig($key, $val); progress (($rc == 0) ? "done.\n" : "failed.\n"); configLog($key); } } sub configSetNEFeatures { return unless isNetwork(); } sub configInitDomainAdminGroups { return if ($config{DOCREATEDOMAIN} eq "no"); main::progress ("Setting up default domain admin UI components..."); $config{zimbraDefaultDomainName} = getLdapConfigValue("zimbraDefaultDomainName") || $config{CREATEDOMAIN}; my $domainGroup = "zimbraDomainAdmins\@". (($newinstall) ? "$config{CREATEDOMAIN}" : "$config{zimbraDefaultDomainName}"); my $rc = main::runAsZimbra("$ZMPROV cdl $domainGroup ". "zimbraIsAdminGroup TRUE ". "zimbraHideInGal TRUE ". "zimbraMailStatus disabled ". "displayname 'Zimbra Domain Admins' ". "zimbraAdminConsoleUIComponents accountListView ". "zimbraAdminConsoleUIComponents aliasListView ". "zimbraAdminConsoleUIComponents DLListView ". "zimbraAdminConsoleUIComponents resourceListView ". "zimbraAdminConsoleUIComponents saveSearch "); main::progress(($rc == 0) ? "done.\n" : "failed.\n"); main::progress ("Granting group $domainGroup domain right +domainAdminConsoleRights on $config{zimbraDefaultDomainName}..."); $rc = main::runAsZimbra("$ZMPROV grr domain $config{zimbraDefaultDomainName} grp $domainGroup +domainAdminConsoleRights"); main::progress(($rc == 0) ? "done.\n" : "failed.\n"); main::progress ("Granting group $domainGroup global right +domainAdminZimletRights..."); $rc = main::runAsZimbra("$ZMPROV grr global grp $domainGroup +domainAdminZimletRights"); main::progress(($rc == 0) ? "done.\n" : "failed.\n"); main::progress ("Setting up global distribution list admin UI components.."); $domainGroup = "zimbraDLAdmins\@". (($newinstall) ? "$config{CREATEDOMAIN}" : "$config{zimbraDefaultDomainName}"); my $rc = main::runAsZimbra("$ZMPROV cdl $domainGroup ". "zimbraIsAdminGroup TRUE ". "zimbraHideInGal TRUE ". "zimbraMailStatus disabled ". "displayname 'Zimbra DL Admins' ". "zimbraAdminConsoleUIComponents DLListView "); main::progress(($rc == 0) ? "done.\n" : "failed.\n"); main::progress ("Granting group $domainGroup global right +adminConsoleDLRights..."); $rc = main::runAsZimbra("$ZMPROV grr global grp $domainGroup +adminConsoleDLRights"); main::progress(($rc == 0) ? "done.\n" : "failed.\n"); main::progress ("Granting group $domainGroup global right +listAccount..."); $rc = main::runAsZimbra("$ZMPROV grr global grp $domainGroup +listAccount"); main::progress(($rc == 0) ? "done.\n" : "failed.\n"); } sub configInitBackupPrefs { if (isEnabled("zimbra-store") && isNetwork()) { foreach my $recip (split(/\n/, $config{zimbraBackupReportEmailRecipients})) { setLdapGlobalConfig("+zimbraBackupReportEmailRecipients", $recip); } foreach my $sender (split(/\n/, $config{zimbraBackupReportEmailSender})) { setLdapGlobalConfig("+zimbraBackupReportEmailSender", $sender); } } } sub setProxyBits { detail("Setting Proxy pieces\n"); my $zimbraReverseProxyMailHostQuery = "\(\|\(zimbraMailDeliveryAddress=\${USER}\)\(zimbraMailAlias=\${USER}\)\(zimbraId=\${USER}\)\)"; my $zimbraReverseProxyDomainNameQuery = '\(\&\(zimbraVirtualIPAddress=\${IPADDR}\)\(objectClass=zimbraDomain\)\)'; my $zimbraReverseProxyPortQuery = '\(\&\(zimbraServiceHostname=\${MAILHOST}\)\(objectClass=zimbraServer\)\)'; my @zmprov_args = (); push(@zmprov_args, ('zimbraReverseProxyMailHostQuery', $zimbraReverseProxyMailHostQuery)) if(getLdapConfigValue("zimbraReverseProxyMailHostQuery") eq ""); push(@zmprov_args, ('zimbraReverseProxyPortQuery', $zimbraReverseProxyPortQuery)) if(getLdapConfigValue("zimbraReverseProxyPortQuery") eq ""); push(@zmprov_args, ('zimbraReverseProxyDomainNameQuery', $zimbraReverseProxyDomainNameQuery)) if(getLdapConfigValue("zimbraReverseProxyDomainNameQuery") eq ""); push(@zmprov_args, ('zimbraMemcachedBindPort', '11211')) if(getLdapConfigValue("zimbraMemcachedBindPort") eq ""); push(@zmprov_args, ('zimbraReverseProxyMailHostAttribute', 'zimbraMailHost')) if(getLdapConfigValue("zimbraReverseProxyMailHostAttribute") eq ""); push(@zmprov_args, ('zimbraReverseProxyPop3PortAttribute', 'zimbraPop3BindPort')) if(getLdapConfigValue("zimbraReverseProxyPop3PortAttribute") eq ""); push(@zmprov_args, ('zimbraReverseProxyPop3SSLPortAttribute', 'zimbraPop3SSLBindPort')) if(getLdapConfigValue("zimbraReverseProxyPop3SSLPortAttribute") eq ""); push(@zmprov_args, ('zimbraReverseProxyImapPortAttribute', 'zimbraImapBindPort')) if(getLdapConfigValue("zimbraReverseProxyImapPortAttribute") eq ""); push(@zmprov_args, ('zimbraReverseProxyImapSSLPortAttribute', 'zimbraImapSSLBindPort')) if(getLdapConfigValue("zimbraReverseProxyImapSSLPortAttribute") eq ""); push(@zmprov_args, ('zimbraReverseProxyDomainNameAttribute', 'zimbraDomainName')) if(getLdapConfigValue("zimbraReverseProxyDomainNameAttribute") eq ""); push(@zmprov_args, ('zimbraImapCleartextLoginEnabled', 'FALSE')) if(getLdapConfigValue("zimbraImapCleartextLoginEnabled") eq ""); push(@zmprov_args, ('zimbraPop3CleartextLoginEnabled', 'FALSE')) if(getLdapConfigValue("zimbraPop3CleartextLoginEnabled") eq ""); push(@zmprov_args, ('zimbraReverseProxyAuthWaitInterval', '10s')) if(getLdapConfigValue("zimbraReverseProxyAuthWaitInterval") eq ""); push(@zmprov_args, ('zimbraReverseProxyIPLoginLimit', '0')) if(getLdapConfigValue("zimbraReverseProxyIPLoginLimit") eq ""); push(@zmprov_args, ('zimbraReverseProxyIPLoginLimitTime', '3600')) if(getLdapConfigValue("zimbraReverseProxyIPLoginLimitTime") eq ""); push(@zmprov_args, ('zimbraReverseProxyUserLoginLimit', '0')) if(getLdapConfigValue("zimbraReverseProxyUserLoginLimit") eq ""); push(@zmprov_args, ('zimbraReverseProxyUserLoginLimitTime', '3600')) if(getLdapConfigValue("zimbraReverseProxyUserLoginLimitTime") eq ""); push(@zmprov_args, ('zimbraMailProxyPort', '0')) if(getLdapConfigValue("zimbraMailProxyPort") eq ""); push(@zmprov_args, ('zimbraMailSSLProxyPort', '0')) if(getLdapConfigValue("zimbraMailSSLProxyPort") eq ""); push(@zmprov_args, ('zimbraReverseProxyHttpEnabled', 'FALSE')) if(getLdapConfigValue("zimbraReverseProxyHttpEnabled") eq ""); push(@zmprov_args, ('zimbraReverseProxyMailEnabled', 'TRUE')) if(getLdapConfigValue("zimbraReverseProxyMailEnabled") eq ""); setLdapGlobalConfig( @zmprov_args ); } sub configSetProxyPrefs { if (isEnabled("zimbra-proxy")) { if ($config{STRICTSERVERNAMEENABLED} eq "yes") { progress("Enabling strict server name enforcement on $config{HOSTNAME}..."); runAsZimbra("$ZMPROV ms $config{HOSTNAME} zimbraReverseProxyStrictServerNameEnabled TRUE"); progress("done.\n"); } else { progress("Disabling strict server name enforcement on $config{HOSTNAME}..."); runAsZimbra("$ZMPROV ms $config{HOSTNAME} zimbraReverseProxyStrictServerNameEnabled FALSE"); progress("done.\n"); } if ($config{MAILPROXY} eq "FALSE" && $config{HTTPPROXY} eq "FALSE") { $enabledPackages{"zimbra-proxy"} = "Disabled"; } else { my $upstream="-u"; if ($config{zimbra_require_interprocess_security}) { $upstream="-U"; } if($config{MAILPROXY} eq "TRUE") { runAsZimbra("/opt/zimbra/libexec/zmproxyconfig $upstream -m -e -o ". "-i $config{IMAPPORT}:$config{IMAPPROXYPORT}:$config{IMAPSSLPORT}:$config{IMAPSSLPROXYPORT} ". "-p $config{POPPORT}:$config{POPPROXYPORT}:$config{POPSSLPORT}:$config{POPSSLPROXYPORT} -H $config{HOSTNAME}"); } else { runAsZimbra("/opt/zimbra/libexec/zmproxyconfig -m -d -o ". "-i $config{IMAPPORT}:$config{IMAPPROXYPORT}:$config{IMAPSSLPORT}:$config{IMAPSSLPROXYPORT} ". "-p $config{POPPORT}:$config{POPPROXYPORT}:$config{POPSSLPORT}:$config{POPSSLPROXYPORT} -H $config{HOSTNAME}"); } if ($config{HTTPPROXY} eq "TRUE" ) { runAsZimbra("/opt/zimbra/libexec/zmproxyconfig $upstream -w -e -o ". " -x $config{PROXYMODE} ". "-a $config{HTTPPORT}:$config{HTTPPROXYPORT}:$config{HTTPSPORT}:$config{HTTPSPROXYPORT} -H $config{HOSTNAME}"); } else { runAsZimbra("/opt/zimbra/libexec/zmproxyconfig -w -d -o ". "-x $config{MODE} ". "-a $config{HTTPPORT}:$config{HTTPPROXYPORT}:$config{HTTPSPORT}:$config{HTTPSPROXYPORT} -H $config{HOSTNAME}"); } } if (!(isEnabled("zimbra-store"))) { my @storetargets; detail("Running $ZMPROV garpu"); open(ZMPROV, "$ZMPROV garpu 2>/dev/null|"); chomp(@storetargets = ); close(ZMPROV); if ( $storetargets[0] !~ /nginx-lookup/ ) { progress("WARNING: There is currently no mailstore to proxy. Proxy will restart once one becomes available.\n"); } } if (!(isEnabled("zimbra-memcached"))) { my @memcachetargets; detail("Running $ZMPROV gamcs"); open(ZMPROV, "$ZMPROV gamcs 2>/dev/null|"); chomp(@memcachetargets = ); close(ZMPROV); if ( $memcachetargets[0] !~ /:11211/ ) { progress("WARNING: There are currently no memcached servers for the proxy. Proxy will start once one becomes available.\n"); } } } else { runAsZimbra("/opt/zimbra/libexec/zmproxyconfig -m -d -o ". "-i $config{IMAPPORT}:$config{IMAPPROXYPORT}:$config{IMAPSSLPORT}:$config{IMAPSSLPROXYPORT} ". "-p $config{POPPORT}:$config{POPPROXYPORT}:$config{POPSSLPORT}:$config{POPSSLPROXYPORT} -H $config{HOSTNAME}"); runAsZimbra("/opt/zimbra/libexec/zmproxyconfig -w -d -o ". "-x $config{MODE} ". "-a $config{HTTPPORT}:$config{HTTPPROXYPORT}:$config{HTTPSPORT}:$config{HTTPSPROXYPORT} -H $config{HOSTNAME}"); } } sub removeNetworkComponents { my $components = getLdapConfigValue("zimbraComponentAvailable"); my @zmprov_args = (); foreach my $component (split(/\n/,$components)) { push(@zmprov_args, ('-zimbraComponentAvailable', $component)) if ($component =~ /HSM|convertd|archiving|hotbackup/); if ($component =~ /convertd/) { my $rc = 0; progress ("Removing convertd mime tree from ldap..."); my $ldap_pass = getLocalConfig("zimbra_ldap_password"); my $ldap_master_url = getLocalConfig("ldap_master_url"); my $ldap; my @masters=split(/ /, $ldap_master_url); my $master_ref=\@masters; unless($ldap = Net::LDAP->new($master_ref)) { detail("Unable to contact $ldap_master_url: $!"); $rc = 1; } my $ldap_dn = $config{zimbra_ldap_userdn}; my $ldap_base = ""; my $result = $ldap->bind($ldap_dn, password => $ldap_pass); if ($result->code()) { detail("ldap bind failed for $ldap_dn"); $rc = 1; } else { $result = $ldap->modify('cn=text/enriched,cn=mime,cn=config,cn=zimbra', replace => [ 'zimbraMimeHandlerClass' => 'TextEnrichedHandler' ] ); $result = $ldap->modify('cn=text/plain,cn=mime,cn=config,cn=zimbra', replace => [ 'zimbraMimeHandlerClass' => 'TextPlainHandler' ] ); $result = $ldap->modify('cn=all,cn=mime,cn=config,cn=zimbra', changes => [ replace => [ 'zimbraMimeHandlerClass' => 'UnknownTypeHandler' ], delete => [ 'zimbraMimeHandlerExtension' => []] ] ); $result = $ldap->delete('cn=application/x-zip-compressed,cn=mime,cn=config,cn=zimbra'); $result = $ldap->delete('cn=application/zip,cn=mime,cn=config,cn=zimbra'); $result = $ldap->delete('cn=text/rtf,cn=mime,cn=config,cn=zimbra'); $result = $ldap->delete('cn=unsupported,cn=mime,cn=config,cn=zimbra'); $result = $ldap->unbind; $result = $ldap->disconnect; } progress (($rc == 0) ? "done.\n" : "failed. This may impact system functionality.\n"); progress ("Removing convertd from zimbraServiceEnabled list..."); my $rc = setLdapServerConfig($config{HOSTNAME}, '-zimbraServiceEnabled', 'convertd'); progress (($rc == 0) ? "done.\n" : "failed. This may impact system functionality.\n"); } } if (@zmprov_args) { progress ("Removing network components from ldap..."); my $rc = setLdapGlobalConfig( @zmprov_args ); progress (($rc == 0) ? "done.\n" : "failed. This may impact system functionality.\n"); } foreach my $zimlet (qw(com_zimbra_backuprestore com_zimbra_convertd com_zimbra_domainadmin com_zimbra_hsm com_zimbra_license com_zimbra_mobilesync zimbra_xmbxsearch com_zimbra_xmbxsearch com_zimbra_smime_cert_admin com_zimbra_delegatedadmin com_zimbra_smime com_zimbra_two_factor_auth)) { system("rm -rf $config{mailboxd_directory}/webapps/service/zimlet/$zimlet") if (-d "$config{mailboxd_directory}/webapps/service/zimlet/$zimlet" ); system("rm -rf /opt/zimbra/zimlets-deployed/$zimlet") if (-d "/opt/zimbra/zimlets-deployed/$zimlet" ); } if (isEnabled("zimbra-ldap") && -x "/opt/zimbra/libexec/zmconvertdmod") { progress ("Removing convertd mime tree from ldap..."); my $rc = runAsZimbra("/opt/zimbra/libexec/zmconvertdmod -d"); progress (($rc == 0) ? "done.\n" : "failed. This may impact system functionality.\n"); } setLdapGlobalConfig("zimbraReverseProxyUpstreamEwsServers",""); } sub countReverseProxyLookupTargets { my $count = 0; my $ldap_pass = getLocalConfig("zimbra_ldap_password"); my $ldap_master_url = getLocalConfig("ldap_master_url"); my $ldap; my @masters=split(/ /, $ldap_master_url); my $master_ref=\@masters; unless($ldap = Net::LDAP->new($master_ref)) { detail("Unable to contact $ldap_master_url: $!"); return; } my $ldap_dn = $config{zimbra_ldap_userdn}; my $ldap_base = ""; my $result = $ldap->bind($ldap_dn, password => $ldap_pass); if ($result->code()) { detail("ldap bind failed for $ldap_dn"); return; } else { detail("ldap bind done for $ldap_dn"); progress("Searching LDAP for reverseProxyLookupTargets..."); $result = $ldap->search(base => 'cn=zimbra', filter => '(zimbraReverseProxyLookupTarget=TRUE)', attrs => ['1.1']); progress (($result->code()) ? "failed.\n" : "done.\n"); return if ($result->code()); $count = $result->count; } return "$count"; } sub countUsers { return $main::loaded{stats}{numAccts} if (exists $main::loaded{stats}{numAccts}); my $count = 0; my $ldap_pass = getLocalConfig("zimbra_ldap_password"); my $ldap_master_url = getLocalConfig("ldap_master_url"); my $ldap; my @masters=split(/ /, $ldap_master_url); my $master_ref=\@masters; unless($ldap = Net::LDAP->new($master_ref)) { detail("Unable to contact $ldap_master_url: $!"); return undef; } my $ldap_dn = $config{zimbra_ldap_userdn}; my $ldap_base = ""; my $result = $ldap->bind($ldap_dn, password => $ldap_pass); if ($result->code()) { detail("ldap bind failed for $ldap_dn"); return undef; } else { detail("ldap bind done for $ldap_dn"); progress("Searching LDAP for zimbra accounts..."); $result = $ldap->search(filter => "(objectclass=zimbraAccount)", \ attrs => ['zimbraMailDeliveryAddress']); progress (($result->code()) ? "failed.\n" : "done.\n"); return undef if ($result->code()); $count = $result->count; } $result = $ldap->unbind; $main::loaded{stats}{numAccts} = $count if ($count > 0); return(($count > 0) ? "$count" : undef); } sub removeNetworkZimlets { my $ldap_pass = getLocalConfig("zimbra_ldap_password"); my $ldap_master_url = getLocalConfig("ldap_master_url"); my $ldap; my @masters=split(/ /, $ldap_master_url); my $master_ref=\@masters; unless($ldap = Net::LDAP->new($master_ref)) { detail("Unable to contact $ldap_master_url: $!"); return 1; } my $ldap_dn = $config{zimbra_ldap_userdn}; my $ldap_base = "cn=zimlets,$config{ldap_dit_base_dn_config}"; my $result = $ldap->bind($ldap_dn, password => $ldap_pass); if ($result->code()) { detail("ldap bind failed for $ldap_dn"); return 1; } else { detail("ldap bind done for $ldap_dn"); progress("Checking for network zimlets in LDAP..."); $result = $ldap->search(base => $ldap_base, scope => 'one', filter => "(|(cn=com_zimbra_backuprestore)(cn=com_zimbra_domainadmin)(cn=com_zimbra_mobilesync)(cn=com_zimbra_hsm)(cn=com_zimbra_convertd)(cn=com_zimbra_license)(cn=zimbra_xmbxsearch)(cn=com_zimbra_xmbxsearch)(cn=com_zimbra_smime)(cn=com_zimbra_smime_cert_admin)(cn=com_zimbra_two_factor_auth))", attrs => ['cn']); progress (($result->code()) ? "failed.\n" : "done.\n"); return $result if ($result->code()); detail("Processing ldap search results"); progress("Removing network zimlets...\n"); foreach my $entry ($result->all_entries) { my $zimlet = $entry->get_value('cn'); if ( $zimlet ne "" ) { progress("\tRemoving $zimlet..."); my $rc = runAsZimbra("/opt/zimbra/bin/zmzimletctl -l undeploy $zimlet"); progress (($rc == 0) ? "done.\n" : "failed. This may impact system functionality.\n"); } } progress("Finished removing network zimlets.\n"); } $result = $ldap->unbind; return 0; } sub zimletCleanup { my $ldap_pass = getLocalConfig("zimbra_ldap_password"); my $ldap_master_url = getLocalConfig("ldap_master_url"); my $ldap; my @masters=split(/ /, $ldap_master_url); my $master_ref=\@masters; unless($ldap = Net::LDAP->new($master_ref)) { detail("Unable to contact $ldap_master_url: $!"); return 1; } my $ldap_dn = $config{zimbra_ldap_userdn}; my $ldap_base = "cn=zimlets,$config{ldap_dit_base_dn_config}"; my $result = $ldap->bind($ldap_dn, password => $ldap_pass); if ($result->code()) { detail("ldap bind failed for $ldap_dn"); return 1; } else { detail("ldap bind done for $ldap_dn"); $result = $ldap->search(base => $ldap_base, scope => 'one', filter => "(|(cn=convertd)(cn=hsm)(cn=hotbackup)(cn=zimbra_cert_manager)(cn=com_zimbra_search)(cn=zimbra_xmbxsearch)(cn=com_zimbra_domainadmin)(cn=com_zimbra_tinymce)(cn=com_zimbra_tasksreminder)(cn=com_zimbra_linkedin)(cn=com_zimbra_social)(cn=com_zimbra_dnd)(cn=com_zextras_chat_open)(cn=com_zextras_talk)(cn=com_zimbra_smime)(cn=zimbra-zimlet-restore-contacts)(cn=zimbra-zimlet-duplicate-contacts))", attrs => ['cn']); return $result if ($result->code()); detail("Processing ldap search results"); foreach my $entry ($result->all_entries) { my $zimlet = $entry->get_value('cn'); if ( $zimlet ne "" ) { detail("Removing $zimlet"); runAsZimbra("/opt/zimbra/bin/zmzimletctl -l undeploy $zimlet"); system("rm -rf $config{mailboxd_directory}/webapps/service/zimlet/$zimlet") if (-d "$config{mailboxd_directory}/webapps/service/zimlet/$zimlet" ); system("rm -rf /opt/zimbra/jetty/webapps/zimbra/public/${zimlet}.jarx") if (-f "/opt/zimbra/jetty/webapps/zimbra/public/${zimlet}.jarx" ); system("rm -rf /opt/zimbra/zimlets-deployed/$zimlet") if (-d "/opt/zimbra/zimlets-deployed/$zimlet" ); system("rm -rf /opt/zimbra/zimlets-network/${zimlet}.zip") if (-f "/opt/zimbra/zimlets-network/${zimlet}.zip" ); system("rm -rf /opt/zimbra/zimlets/${zimlet}.zip") if (-f "/opt/zimbra/zimlets/${zimlet}.zip" ); } } } $result = $ldap->unbind; return 0; } sub configInstallZimlets { if ($configStatus{configInstallZimlets} eq "CONFIGURED") { configLog("configInstallZimlets"); return 0; } my $zimlet_directory = getLocalConfig("zimlet_directory") || "/opt/zimbra/zimlets-deployed"; my $zimlet_properties = getLocalConfig("zimlet_properties_directory") || "/opt/zimbra/zimlets-properties"; my (undef,undef,$uid,$gid) = getpwnam("zimbra"); mkdir($zimlet_directory) if (! -d $zimlet_directory); chown($uid,$gid, $zimlet_directory); chmod(0755, $zimlet_directory); system("/bin/rm -rf $zimlet_properties") if ( -d $zimlet_properties); # remove deprecated zimlets on upgrades if (!$newinstall) { progress("Checking for deprecated zimlets..."); progress((zimletCleanup()) ? "failed.\n" : "done.\n"); } # remove any Network zimlets if we are upgrading to a FOSS version if (isFoss() && !$newinstall) { removeNetworkZimlets(); } # Install zimlets if (opendir DIR, "/opt/zimbra/zimlets") { progress ( "Installing common zimlets...\n" ); my @core_zimlets = (qw(com_zimbra_dnd com_zimbra_url com_zimbra_date com_zimbra_email com_zimbra_attachcontacts com_zimbra_attachmail)); my @zimlets = grep { !/^\./ } readdir(DIR); foreach my $zimletfile (@zimlets) { my $zimlet = $zimletfile; $zimlet =~ s/\.zip$//; progress ("\t$zimlet..."); my $rc = runAsZimbra ("/opt/zimbra/bin/zmzimletctl -l deploy zimlets/$zimletfile"); if ($rc == 0) { setLdapCOSConfig("+zimbraZimletAvailableZimlets", "!$zimlet") if (grep(/$zimlet/, @core_zimlets)); progress("done.\n"); } else { progress("failed. This may impact system functionality.\n"); } } progress ( "Finished installing common zimlets.\n" ); } # Install zimlets if (opendir DIR, "/opt/zimbra/zimlets-network") { progress ( "Installing network zimlets...\n" ); my @zimlets = grep { !/^\./ } readdir(DIR); foreach my $zimletfile (@zimlets) { my $zimlet = $zimletfile; $zimlet =~ s/\.zip$//; progress ("\t$zimlet..."); my $rc = runAsZimbra ("/opt/zimbra/bin/zmzimletctl -l deploy zimlets-network/$zimletfile"); progress (($rc == 0) ? "done.\n" : "failed. This may impact system functionality.\n"); # disable click2call zimlets by default. #73987 setLdapCOSConfig("+zimbraZimletAvailableZimlets", "-$zimlet") if ($zimlet =~ /click2call/); } progress ( "Finished installing network zimlets.\n" ); } # Reinstall extras that are deployed on upgrade if (!$newinstall) { my $ldap_pass = getLocalConfig("zimbra_ldap_password"); my $ldap_master_url = getLocalConfig("ldap_master_url"); my $ldap; my @masters=split(/ /, $ldap_master_url); my $master_ref=\@masters; unless($ldap = Net::LDAP->new($master_ref)) { detail("Unable to contact $ldap_master_url: $!"); return 1; } my $ldap_dn = $config{zimbra_ldap_userdn}; my $ldap_base = "cn=zimlets,$config{ldap_dit_base_dn_config}"; my $result = $ldap->bind($ldap_dn, password => $ldap_pass); if ($result->code()) { detail("ldap bind failed for $ldap_dn"); return 1; } else { detail("ldap bind done for $ldap_dn"); progress("Getting list of all zimlets..."); $result = $ldap->search(base => $ldap_base, scope => 'one', filter => '(objectClass=zimbraZimletEntry)', attrs => ['cn']); progress (($result->code()) ? "failed.\n" : "done.\n"); return $result if ($result->code()); progress("Updating non-standard zimlets...\n"); foreach my $entry ($result->all_entries) { my $zimlet = $entry->get_value('cn'); foreach my $type (qw(zimlets-admin-extra zimlets-experimental zimlets-extra)) { if (-e "/opt/zimbra/${type}/${zimlet}.zip") { progress ("\t$zimlet..."); my $rc = runAsZimbra ("/opt/zimbra/bin/zmzimletctl -l deploy ${type}/${zimlet}.zip"); progress (($rc == 0) ? "done.\n" : "failed. This may impact system functionality.\n"); } } } progress("Finished updating non-standard zimlets.\n"); $result = $ldap->unbind; } } configLog("configInstallZimlets"); } sub configCreateDomain { if ($configStatus{configCreateDomain} eq "CONFIGURED") { configLog("configCreateDomain"); return 0; } if (!$ldapConfigured && isEnabled("zimbra-ldap")) { if ($config{DOCREATEDOMAIN} eq "yes") { progress ( "Creating domain $config{CREATEDOMAIN}..." ); my $domainId = getLdapDomainValue("zimbraId"); if ($domainId ne "") { progress("already exists.\n"); } else { my $rc = runAsZimbra("$ZMPROV cd $config{CREATEDOMAIN}"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } progress("Setting default domain name..."); my $rc = setLdapGlobalConfig("zimbraDefaultDomainName", $config{CREATEDOMAIN}); progress(($rc == 0) ? "done.\n" : "failed.\n"); } configInitDomainAdminGroups() if (isNetwork() && isLdapMaster() && isZCS()); } if (isEnabled("zimbra-store")) { if ($config{DOCREATEADMIN} eq "yes") { $config{CREATEADMIN} = lc($config{CREATEADMIN}); my ($u,$d) = split ('@', $config{CREATEADMIN}); progress ("Creating domain $d..."); my $domainId = getLdapDomainValue("zimbraId",$d); if ($domainId ne "") { progress("already exists.\n"); } else { my $rc = runAsZimbra("$ZMPROV cd $d"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } progress ("Creating admin account $config{CREATEADMIN}..."); my $acctId = getLdapAccountValue("zimbraId", $config{CREATEADMIN}); if ($acctId ne "") { progress("already exists.\n"); } else { my $rc = runAsZimbra("$ZMPROV ca ". "$config{CREATEADMIN} \'$config{CREATEADMINPASS}\' ". "zimbraAdminConsoleUIComponents cartBlancheUI ". "description \'Administrative Account\' ". "zimbraIsAdminAccount TRUE"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } # no root/postmaster accounts on web-only nodes if (isStoreServiceNode()) { progress ( "Creating root alias..." ); my $rc = runAsZimbra("$ZMPROV aaa ". "$config{CREATEADMIN} root\@$config{CREATEDOMAIN}"); progress(($rc == 0) ? "done.\n" : "failed.\n"); progress ( "Creating postmaster alias..." ); $rc = runAsZimbra("$ZMPROV aaa ". "$config{CREATEADMIN} postmaster\@$config{CREATEDOMAIN}"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } } if ($config{DOTRAINSA} eq "yes") { $config{TRAINSASPAM} = lc($config{TRAINSASPAM}); progress ( "Creating user $config{TRAINSASPAM}..." ); my $acctId = getLdapAccountValue("zimbraId", $config{TRAINSASPAM}); if ($acctId ne "") { progress("already exists.\n"); } else { my $pass = genRandomPass(); my $rc = runAsZimbra("$ZMPROV ca ". "$config{TRAINSASPAM} \'$pass\' ". "amavisBypassSpamChecks TRUE ". "zimbraAttachmentsIndexingEnabled FALSE ". "zimbraIsSystemResource TRUE ". "zimbraIsSystemAccount TRUE ". "zimbraHideInGal TRUE ". "zimbraMailQuota 0 ". "description \'System account for spam training.\'"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } $config{TRAINSAHAM} = lc($config{TRAINSAHAM}); progress ( "Creating user $config{TRAINSAHAM}..." ); my $acctId = getLdapAccountValue("zimbraId", $config{TRAINSAHAM}); if ($acctId ne "") { progress("already exists.\n"); } else { my $pass = genRandomPass(); my $rc = runAsZimbra("$ZMPROV ca ". "$config{TRAINSAHAM} \'$pass\' ". "amavisBypassSpamChecks TRUE ". "zimbraAttachmentsIndexingEnabled FALSE ". "zimbraIsSystemResource TRUE ". "zimbraIsSystemAccount TRUE ". "zimbraHideInGal TRUE ". "zimbraMailQuota 0 ". "description \'System account for Non-Spam (Ham) training.\'"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } $config{VIRUSQUARANTINE} = lc($config{VIRUSQUARANTINE}); progress ( "Creating user $config{VIRUSQUARANTINE}..." ); my $acctId = getLdapAccountValue("zimbraId", $config{VIRUSQUARANTINE}); if ($acctId ne "") { progress("already exists.\n"); } else { my $pass = genRandomPass(); my $rc = runAsZimbra("$ZMPROV ca ". "$config{VIRUSQUARANTINE} \'$pass\' ". "amavisBypassSpamChecks TRUE ". "zimbraAttachmentsIndexingEnabled FALSE ". "zimbraIsSystemResource TRUE ". "zimbraIsSystemAccount TRUE ". "zimbraHideInGal TRUE ". "zimbraMailMessageLifetime 30d ". "zimbraMailQuota 0 ". "description \'System account for Anti-virus quarantine.\'"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } progress ( "Setting spam training and Anti-virus quarantine accounts..." ); my $rc = setLdapGlobalConfig( 'zimbraSpamIsSpamAccount', "$config{TRAINSASPAM}", 'zimbraSpamIsNotSpamAccount', "$config{TRAINSAHAM}", 'zimbraAmavisQuarantineAccount', "$config{VIRUSQUARANTINE}" ); progress(($rc == 0) ? "done.\n" : "failed.\n"); } } configLog("configCreateDomain"); } sub configInitSql { if ($configStatus{configInitSql} eq "CONFIGURED") { configLog("configInitSql"); return 0; } if (!$sqlConfigured && (isEnabled("zimbra-store") || (isEnabled("zimbra-onlyoffice") && $newinstall && !isEnabled("zimbra-store")) ) ) { progress ( "Initializing store sql database..." ); runAsZimbra ("/opt/zimbra/libexec/zmmyinit --mysql_memory_percent $config{MYSQLMEMORYPERCENT}"); progress ( "done.\n" ); progress ( "Setting zimbraSmtpHostname for $config{HOSTNAME}..." ); #SMTP host can be one or more values seperated by comma or space. my @smtphost = split /[,\s]+/, $config{SMTPHOST}; foreach(@smtphost) { my $rc = setLdapServerConfig("+zimbraSmtpHostname", $_); progress(($rc == 0) ? "done.\n" : "failed.\n"); } } configLog("configInitSql"); } sub configInitLogger { if ($configStatus{configInitLogger} eq "CONFIGURED") { configLog("configInitLogger"); return 0; } if (isEnabled("zimbra-logger")) { setLdapGlobalConfig("zimbraLogHostname", $config{HOSTNAME}); setLocalConfig ("smtp_source", $config{SMTPSOURCE}); setLocalConfig ("smtp_destination", $config{SMTPDEST}); } configLog("configInitLogger"); } sub configInitCore { if ($configStatus{configInitCore} eq "CONFIGURED") { configLog("configInitCore"); return 0; } if (isEnabled("zimbra-core")) { progress ( "Initializing core config..." ); if(isNetwork()) { if ($config{RUNVMHA} eq "yes") { push(@enabledServiceList, ('zimbraServiceEnabled', 'vmware-ha')); } } } configLog("configInitCore"); } sub configInitMta { if ($configStatus{configInitMta} eq "CONFIGURED") { configLog("configInitMta"); return 0; } if (isEnabled("zimbra-mta")) { progress ( "Initializing mta config..." ); setLocalConfig("postfix_mail_owner", $config{postfix_mail_owner}); setLocalConfig("postfix_setgid_group", $config{postfix_setgid_group}); runAsZimbra ("/opt/zimbra/libexec/zmmtainit $config{LDAPHOST} $config{LDAPPORT}"); progress ( "done.\n" ); if (isZCS()) { push(@installedServiceList, ('zimbraServiceInstalled', 'amavis')); push(@installedServiceList, ('zimbraServiceInstalled', 'antivirus')); push(@installedServiceList, ('zimbraServiceInstalled', 'antispam')); push(@installedServiceList, ('zimbraServiceInstalled', 'opendkim')); push(@enabledServiceList, ('zimbraServiceEnabled', 'amavis')); if ($config{RUNAV} eq "yes") { push(@enabledServiceList, ('zimbraServiceEnabled', 'antivirus')); } if ($config{RUNARCHIVING} eq "yes") { push(@installedServiceList, ('zimbraServiceInstalled', 'archiving')); push(@enabledServiceList, ('zimbraServiceEnabled', 'archiving')); } if ($config{RUNSA} eq "yes") { push(@enabledServiceList, ('zimbraServiceEnabled', 'antispam')); } if ($config{RUNDKIM} eq "yes") { push(@enabledServiceList, ('zimbraServiceEnabled', 'opendkim')); } if ($config{RUNCBPOLICYD} eq "yes") { push(@enabledServiceList, ('zimbraServiceEnabled', 'cbpolicyd')); } } setLdapServerConfig("zimbraMtaMyNetworks", $config{zimbraMtaMyNetworks}) if ($config{zimbraMtaMyNetworks} ne ""); } configLog("configInitMta"); } sub configInitSnmp { if ($configStatus{configInitSnmp} eq "CONFIGURED") { configLog("configInitSnmp"); return 0; } if (isEnabled("zimbra-snmp")) { progress ( "Configuring SNMP..." ); setLocalConfig ("snmp_notify", $config{SNMPNOTIFY}); setLocalConfig ("smtp_notify", $config{SMTPNOTIFY}); setLocalConfig ("snmp_trap_host", $config{SNMPTRAPHOST}); setLocalConfig ("smtp_source", $config{SMTPSOURCE}); setLocalConfig ("smtp_destination", $config{SMTPDEST}); runAsZimbra ("/opt/zimbra/libexec/zmsnmpinit"); progress ( "done.\n" ); } configLog("configInitSnmp"); } sub configInitGALSyncAccts { if ($configStatus{configInitGALSyncAccts} eq "CONFIGURED") { configLog("configInitGALSyncAccts"); return 0; } return 1 unless (isEnabled("zimbra-ldap") && $config{LDAPHOST} eq $config{HOSTNAME}); #if ($config{ENABLEGALSYNCACCOUNTS} eq "yes") { #progress("Creating galsync accounts in all domains..."); #my $rc = runAsZimbra("zmjava com.zimbra.cs.account.ldap.upgrade.LdapUpgrade -b 14531 -v"); #progress(($rc == 0) ? "done.\n" : "failed.\n"); #configLog("configInitGALSyncAccts") if ($rc == 0); #} } sub configCreateDefaultDomainGALSyncAcct { if ($configStatus{configCreateDefaultGALSyncAcct} eq "CONFIGURED") { configLog("configCreateDefaultGALSyncAcct"); return 0; } if (isEnabled("zimbra-store")) { progress("Creating galsync account for default domain..."); my $zimbra_server = getLocalConfig ("zimbra_server_hostname"); my $default_domain = (($newinstall) ? "$config{CREATEDOMAIN}" : "$config{zimbraDefaultDomainName}"); my $galsyncacct = "galsync." . lc(genRandomPass()) . '@' . $default_domain ; my $rc = runAsZimbra("/opt/zimbra/bin/zmgsautil createAccount -a $galsyncacct -n InternalGAL --domain $default_domain -s $zimbra_server -t zimbra -f _InternalGAL"); progress(($rc == 0) ? "done.\n" : "failed.\n"); configLog("configCreateDefaultDomainGALSyncAcct") if ($rc == 0); } } sub configImap { progress("Enabling IMAP protocol for zimbra-imapd service..."); runAsZimbra("$ZMPROV mcf zimbraRemoteImapServerEnabled TRUE"); progress("done.\n"); progress("Enabling IMAPS protocol for zimbra-imapd service..."); runAsZimbra("$ZMPROV mcf zimbraRemoteImapSSLServerEnabled TRUE"); progress("done.\n"); if ($config{DOADDUPSTREAMIMAP} eq "yes") { progress("Adding $config{HOSTNAME} to list of zimbraReverseProxyUpstreamImapServers..."); runAsZimbra("$ZMPROV mcf +zimbraReverseProxyUpstreamImapServers $config{HOSTNAME}"); progress("done.\n"); progress("Disabling IMAP protocol in mailboxd..."); runAsZimbra("$ZMPROV mcf zimbraImapServerEnabled FALSE"); progress("done.\n"); progress("Disabling IMAPS protocol in mailboxd..."); runAsZimbra("$ZMPROV mcf zimbraImapSSLServerEnabled FALSE"); progress("done.\n"); } } sub configSetEnabledServices { if ($configStatus{configSetEnabledServices} eq "CONFIGURED") { configLog("configSetEnabledServices"); return 0; } foreach my $p (keys %installedPackages) { if ($p eq "zimbra-core") { push(@installedServiceList, ('zimbraServiceInstalled','stats')); if(isNetwork()) { if ( -x "/usr/lib/vmware-tools/sbin64/vmware-checkvm" || $config{INSTVMHA} eq "yes") { my $rc = runAsRoot("/usr/lib/vmware-tools/sbin64/vmware-checkvm"); if ($rc == 0 || $config{INSTVMHA} eq "yes") { push(@installedServiceList, ('zimbraServiceInstalled','vmware-ha')); } } } next; } if ($p eq "zimbra-apache") {next;} if ($p eq "zimbra-archiving") {next;} $p =~ s/zimbra-//; if ($p eq "store") {$p = "mailbox";} if ($p eq "license-daemon") { if (isInstalled("zimbra-${p}")) { $p = "license-daemon"; } else { next; } } push(@installedServiceList, ('zimbraServiceInstalled', "$p")); } foreach my $p (keys %enabledPackages) { if ($p eq "zimbra-core") { push(@enabledServiceList, ('zimbraServiceEnabled', 'stats')); next; } if ($p eq "zimbra-apache") {next;} if ($p eq "zimbra-archiving") {next;} if ($enabledPackages{$p} eq "Enabled") { $p =~ s/zimbra-//; if ($p eq "store") { $p = "mailbox"; # Add zimbra-store webapps to service list foreach my $app (@webappList) { if ($installedWebapps{$app} eq "Enabled") { push(@enabledServiceList, 'zimbraServiceEnabled', "$app"); } } } if ($p eq "license-daemon") { if (isInstalled("zimbra-${p}")) { $p = "license-daemon"; } else { next; } } push(@enabledServiceList, 'zimbraServiceEnabled', "$p"); } } progress ( "Setting services on $config{HOSTNAME}..." ); setLdapServerConfig($config{HOSTNAME}, @installedServiceList); setLdapServerConfig($config{HOSTNAME}, @enabledServiceList); progress ( "done.\n" ); my $rc = runAsZimbra("/opt/zimbra/libexec/zmiptool >/dev/null 2>/dev/null"); configLog("configSetEnabledServices"); } sub failConfig { progress ("\n\nERROR\n\n"); progress ("\n\nConfiguration failed\n\n"); progress ("Please address the error and re-run /opt/zimbra/libexec/zmsetup.pl to\n"); progress ("complete the configuration.\n"); progress ("\nErrors have been logged to $logfile\n\n"); exit 1; } sub applyConfig { defineInstallWebapps(); if (!(defined ($options{c})) && $newinstall ) { if (askYN("Save configuration data to a file?", "Yes") eq "yes") { saveConfig(); } if (askYN("The system will be modified - continue?", "No") eq "no") { return 1; } } else { saveConfig(); } progress ( "Operations logged to $logfile\n" ); if ($newinstall) { open (H, ">>/opt/zimbra/.install_history"); print H time(),": CONFIG SESSION START\n"; # This is the postinstall config configLog ("BEGIN"); } # On split store node setups, the unused webapps need to be removed before # applying any other configuration in order to ensure the installedWebapps # variables are properly setup for later steps. if (isEnabled("zimbra-store")) { removeUnusedWebapps(); } configLCValues(); configInitCore(); # About SSL # # On the master ldap server, create a ca and a cert # On store and MTA servers, just create a cert. # # Non-ldap masters use the master CA, which they get from ldap # but ldap won't start without a cert. # # so - ldap - create CA, create cert, init ldap, store CA in ldap # # non-ldap - fetch CA, create cert configCASetup(); configCreateCert(); configInstallCert(); if ($ldapReplica) { configCreateServerEntry(); } configSetupLdap(); if (!$ldapReplica) { configCreateServerEntry(); } configSaveCA(); configSaveCert(); # Added the following for bug 103803. Could not just add the cert as a globalConfigValue # for zimbraSSldHParam. See bug 104244. setLdapGlobalConfig("zimbraSSLDHParam", "/opt/zimbra/conf/dhparam.pem.zcs") if $newinstall; if (isEnabled("zimbra-store")) { configSpellServer(); configSetServicePorts(); configSetKeyboardShortcutsPref() if (!$newinstall); configInitBackupPrefs(); configSetCEFeatures() if isZCS(); configSetNEFeatures() if isNetwork(); configSetStoreDefaults(); } configSetupEphemeralBackend(); if (isNetwork() && isEnabled("zimbra-convertd")) { configConvertdURL(); runAsZimbra("/opt/zimbra/libexec/zmconvertdmod -e"); } if (isEnabled("zimbra-dnscache")) { configSetDNSCacheDefaults(); } configLDAPSchemaVersion(); if (isEnabled("zimbra-ldap")) { configSetTimeZonePref(); # 32295 setLdapGlobalConfig("zimbraSkinLogoURL", "http://www.zimbra.com") if isFoss(); } if ($newinstall && isInstalled("zimbra-proxy")) { configSetProxyPrefs(); } if( (!$newinstall) && isInstalled("zimbra-ldap") ){ setProxyBits(); } configInitMta(); configureLicenseDaemonService(); configSetEnabledServices(); if (isEnabled("zimbra-store")) { if (isStoreServiceNode()) { addServerToHostPool(); } # bug 100730 if ($config{UIWEBAPPS} eq "no") { setLdapServerConfig($config{HOSTNAME}, "zimbraReverseProxyHttpEnabled", "FALSE"); } } configCreateDomain(); # onlyoffice if (isEnabled("zimbra-onlyoffice") && !isEnabled("zimbra-store") && ( $newinstall || $configStatus{configOnlyoffice} ne "CONFIGURED") ) { ##create the directories required createDirForStandaloneOnlyoffice(); setLocalConfig ("mysql_bind_address", '127.0.0.1'); if ( !-e "/etc/sudoers.d/02_zimbra-store") { system("echo \"%zimbra ALL=NOPASSWD:/opt/zimbra/libexec/zmmailboxdmgr\" > /etc/sudoers.d/02_zimbra-store"); system("chmod 440 /etc/sudoers.d/02_zimbra-store"); } } configInitSql(); configInitLogger(); configInitSnmp(); configInitGALSyncAccts(); setupSyslog(); postinstall::configure(); qx(touch /opt/zimbra/.bash_history); qx(chown zimbra:zimbra /opt/zimbra/.bash_history); if (isFoss() && !$newinstall) { startLdap() if ($ldapConfigured); removeNetworkComponents(); } setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersion', $curVersion); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMajor', $curVersionMajor); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMinor', $curVersionMinor); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionMicro', $curVersionMicroMicro); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionType', $curVersionType); setLdapServerConfig($config{HOSTNAME}, 'zimbraServerVersionBuild', $curVersionBuild); if (isEnabled("zimbra-imapd")) { configImap(); } if (getLdapConfigValue("zimbraLicenseNotificationEmail") eq "") { progress("Setting zimbraLicenseNotificationEmail..."); setLdapGlobalConfig("zimbraLicenseNotificationEmail", $config{CREATEADMIN}); progress("done.\n"); } configureOnlyoffice(); if ($config{STARTSERVERS} eq "yes") { # bug 6270 if (isEnabled("zimbra-store")) { qx(chown zimbra:zimbra /opt/zimbra/redolog/redo.log) if (($platform =~ m/DEBIAN/ || $platform =~ m/UBUNTU/) && ! $newinstall); } sub prevVersionBelow880 { if (($prevVersionMajor < 8) || ($prevVersionMajor = 8 && $prevVersionMinor < 8)) { return 1; } } # Disable zextras modules my $zimbraNetworkModulesNGEnabled = getLdapServerValue("zimbraNetworkModulesNGEnabled"); if ($zimbraNetworkModulesNGEnabled eq "TRUE"){ setLdapServerConfig($config{HOSTNAME}, 'zimbraNetworkModulesNGEnabled', 'FALSE'); } my $zimbraNetworkAdminEnabled = getLdapServerValue("zimbraNetworkAdminEnabled"); if ($zimbraNetworkAdminEnabled eq "TRUE"){ setLdapServerConfig($config{HOSTNAME}, 'zimbraNetworkAdminEnabled', 'FALSE'); } my $zimbraNetworkAdminNGEnabled = getLdapServerValue("zimbraNetworkAdminNGEnabled"); if ($zimbraNetworkAdminNGEnabled eq "TRUE"){ setLdapServerConfig($config{HOSTNAME}, 'zimbraNetworkAdminNGEnabled', 'FALSE'); } my $zimbraNetworkMobileNGEnabled = getLdapServerValue("zimbraNetworkMobileNGEnabled"); if ($zimbraNetworkMobileNGEnabled eq "TRUE"){ setLdapServerConfig($config{HOSTNAME}, 'zimbraNetworkMobileNGEnabled', 'FALSE'); } enableTLSv1_3(); addJDK17Options(); runAsZimbra ("/opt/zimbra/bin/zmcontrol stop" ); if (isInstalled("zimbra-license-daemon")) { runAsZimbra ("/opt/zimbra/bin/zmlicensectl --service stop"); } if (isInstalled("zimbra-ldap") && isEnabled("zimbra-ldap")) { startLdap(); } progress ("Starting servers..."); runAsZimbra ("/opt/zimbra/bin/zmlicensectl --service start") if isLicenseDaemonConfigured(); runAsZimbra ("/opt/zimbra/bin/zmcontrol start"); qx($SU "/opt/zimbra/bin/zmcontrol status"); progress ( "done.\n" ); if ($skip_activation_check =~ /^yes$/i) { progress ("Skipping license activation.\n"); } else { activateLicense(); } # Initialize application server specific items # only after the application server is running. if (isEnabled("zimbra-store")) { progress("Enabling jetty logging..."); system("/opt/zimbra/libexec/zmjettyenablelogging > /dev/null 2>&1"); progress("done.\n"); configInstallZimlets(); progress ( "Restarting mailboxd..."); runAsZimbra("/opt/zimbra/bin/zmmailboxdctl restart"); progress ( "done.\n" ); } if ($newinstall && isStoreServiceNode()) { configCreateDefaultDomainGALSyncAcct(); } else { if ($newinstall) { progress ("Skipping creation of default domain GAL sync account - not a service node.\n"); } else { progress ( "Skipping creation of default domain GAL sync account - existing install detected.\n" ); } } } else { progress ( "WARNING: Document and Zimlet initialization skipped because Application Server was not configured to start.\n". "WARNING: galsync account creation for default domain skipped because Application Server was not configured to start.\n") if (isEnabled("zimbra-store")); } postinstall::notifyZimbra(); setupCrontab(); if ($newinstall) { runAsZimbra ("/opt/zimbra/bin/zmsshkeygen"); runAsZimbra ("/opt/zimbra/bin/zmupdateauthkeys"); } else { runAsZimbra ("/opt/zimbra/bin/zmupdateauthkeys"); } configLog ("END"); print H time(),": CONFIG SESSION COMPLETE\n"; close H; getSystemStatus(); progress ( "\n\n" ); chmod 0600, $logfile; if (-d "/opt/zimbra/log") { main::progress("Moving $logfile to /opt/zimbra/log\n"); system("cp -f $logfile /opt/zimbra/log/"); system("chown zimbra:zimbra /opt/zimbra/log/$logFileName"); } else { progress ( "Operations logged to $logfile\n" ); } progress ( "\n\n" ); # cleanup license option files unlink($license_file) if -e $license_file; unlink("/opt/zimbra/conf/ZCSLicense.xml") if -e "/opt/zimbra/conf/ZCSLicense.xml"; unlink("/opt/zimbra/conf/ZCSLicense-Trial.xml") if -e "/opt/zimbra/conf/ZCSLicense-Trial.xml"; unlink($skip_activation_file) if -e $skip_activation_file; if (!defined ($options{c})) { ask("Configuration complete - press return to exit", ""); print "\n\n"; close LOGFILE; exit 0; } } sub configureOnlyoffice { # create onlyoffice db and configure it if (isEnabled("zimbra-onlyoffice") ) { #enable preview setLdapCOSConfig("zimbraFeatureViewInHTMLEnabled", "TRUE"); # configure onlyoffice print "Configuring Onlyoffice...\n"; open(my $py, "|-", "/opt/zimbra/onlyoffice/bin/zmonlyofficeconfig"); while (<$py>) { print "$py"; } close($py); if ($configStatus{configOnlyoffice} eq "CONFIGURED") { configLog("configOnlyoffice"); return 0; } if ($configStatus{configOnlyoffice} ne "CONFIGURED" || $newinstall) { qx(chmod +x /opt/zimbra/onlyoffice/bin/zmonlyofficeconfig); qx(chmod 775 /opt/zimbra/onlyoffice/bin/process_id.json); qx(chown -R zimbra:zimbra /opt/zimbra/onlyoffice/documentserver/); qx(chown zimbra:zimbra /opt/zimbra/onlyoffice/bin/process_id.json); # on new install if (zmupgrade::startSql()) { return 1; } createOnlyofficeDB(); # set the config value zimbraDocumentServerHost # if standalone server : # 1. global config already present, do not override # 2. global config not present, this server name goes as global config # if not standalone: # set the server host name at server level config if (isEnabled("zimbra-store") && $config{ONLYOFFICESTANDALONE} eq "no") { setLdapServerConfig($config{HOSTNAME}, 'zimbraDocumentServerHost', $config{HOSTNAME}); } else { my $tmpval = getLdapConfigValue("zimbraDocumentServerHost"); if ($tmpval eq "") { setLdapGlobalConfig("zimbraDocumentServerHost", $config{HOSTNAME}); } else { setLdapGlobalConfig("zimbraDocumentServerHost", $config{ONLYOFFICEHOSTNAME}); } } configLog("configOnlyoffice"); } } } sub removePackage { my $pkg = shift; my $pkgrm; if ($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) { $pkgrm = "dpkg --purge"; } else { $pkgrm = "yum -y --disablerepo=* erase -v"; } if (isInstalled($pkg)) { progress ("Removing $pkg from this host..."); my $rc = 0xffff & system ("$pkgrm $pkg > /dev/null 2>&1"); progress (($rc == 0) ? "done.\n" : "failed.\n"); } } sub configureLicenseDaemonService { if (isEnabled("zimbra-license-daemon")) { progress ( "Configuring license daemon service...\n" ); my $licenseDaemonServerHost = getLdapConfigValue("zimbraLicenseDaemonServerHost"); if ($licenseDaemonServerHost ne "" && $licenseDaemonServerHost ne $config{HOSTNAME}) { progress("WARNING: license-daemon service already installed on $licenseDaemonServerHost\n"); removePackage("zimbra-lds-patch"); removePackage("zimbra-license-daemon"); } else { progress("Setting zimbraLicenseDaemonServerHost..."); my $rc = setLdapGlobalConfig("zimbraLicenseDaemonServerHost", $config{HOSTNAME}); progress(($rc == 0) ? "done.\n" : "failed.\n"); } progress ( "done.\n" ); } } sub createDirForStandaloneOnlyoffice { my (undef,undef,$uid,$gid) = getpwnam("zimbra"); my @dir_to_create = ('/opt/zimbra/index', '/opt/zimbra/store', '/opt/zimbra/data/tmp/mysql', '/opt/zimbra/mailboxd', 'opt/zimbra/common/conf'); foreach my $dir (@dir_to_create) { eval { make_path($dir) }; if ($@) { print "Couldn't create $dir: $@"; } else { chown($uid,$gid, $dir); chmod(0755, $dir); } } } sub createOnlyofficeDB { my $mysql_root_pass = getLocalConfig ("mysql_root_password"); progress ( "Creating onlyoffice database..." ); runAsZimbra ("exec /opt/zimbra/common/bin/mysql -S /opt/zimbra/data/tmp/mysql/mysql.sock -u root --password=$mysql_root_pass < /opt/zimbra/onlyoffice/bin/createdb.sql"); progress ( "done.\n" ); } sub configLog { my $stage = shift; my $msg = time().": CONFIGURED $stage\n"; print H $msg; #progress ($msg); } sub setupSyslog { progress ("Setting up syslog.conf..."); if ( -f "/opt/zimbra/libexec/zmsyslogsetup") { my $rc = runAsRoot("/opt/zimbra/libexec/zmsyslogsetup"); if ($rc) { progress ("Failed\n"); } else { progress ("done.\n"); } } else { progress ("Failed\n"); } configLog("setupSyslog"); } sub setupCrontab { my @backupSchedule=(); my $nohsm=1; progress ("Setting up zimbra crontab..."); if ( -x "/opt/zimbra/bin/zmschedulebackup") { detail("Getting current backup schedule in restorable format."); @backupSchedule = (qx($SU "zmschedulebackup -s" 2>> $logfile)); for (my $i=0;$i<=$#backupSchedule;$i++) { $backupSchedule[$i] =~ s/"/\\"/g; } if (scalar @backupSchedule == 0) { detail("Backup schedule was not previously defined"); } else { detail("Retrieved backup schedule:\n @backupSchedule"); } } detail("crontab: Taking a copy of zimbra user crontab file."); if ($platform =~ /SUSE/i) { if (-e '/var/spool/cron/tabs/zimbra') { qx(cp -f /var/spool/cron/tabs/zimbra /tmp/crontab.zimbra.orig); } else { unlink("/tmp/crontab.zimbra.orig"); qx(touch /tmp/crontab.zimbra.orig); } } else { qx(crontab -u zimbra -l > /tmp/crontab.zimbra.orig 2> /dev/null); } $nohsm = 0xffff & system("grep '/opt/zimbra/bin/zmhsm[[:space:]]\\+-t' /tmp/crontab.zimbra.orig > /dev/null 2>&1"); if (!$nohsm) { detail("HSM is in use, no backup schedule required"); } detail("crontab: Looking for ZIMBRASTART in existing crontab entry."); my $rc = 0xffff & system("grep ZIMBRASTART /tmp/crontab.zimbra.orig > /dev/null 2>&1"); if ($rc) { detail("crontab: ZIMBRASTART not found truncating zimbra crontab and starting fresh."); qx(cp -f /dev/null /tmp/crontab.zimbra.orig 2>> $logfile); } detail("crontab: Looking for ZIMBRAEND in existing crontab entry."); $rc = 0xffff & system("grep ZIMBRAEND /tmp/crontab.zimbra.orig > /dev/null 2>&1"); if ($rc) { detail("crontab: ZIMBRAEND not found truncating zimbra crontab and starting fresh."); qx(cp -f /dev/null /tmp/crontab.zimbra.orig); } detail("crontab: Getting existing backup and custom entries from crontab file."); qx(cat /tmp/crontab.zimbra.orig | sed -e '/# ZIMBRASTART/,/# ZIMBRAEND/d' > /tmp/crontab.zimbra.proc); detail("crontab: Adding zimbra-core specific crontab entries"); qx(cp -f /opt/zimbra/conf/crontabs/crontab /tmp/crontab.zimbra); if (isEnabled("zimbra-ldap")) { detail("crontab: Adding zimbra-ldap specific crontab entries"); qx(cat /opt/zimbra/conf/crontabs/crontab.ldap >> /tmp/crontab.zimbra 2>> $logfile); } if (isEnabled("zimbra-store")) { detail("crontab: Adding zimbra-store specific crontab entries"); qx(cat /opt/zimbra/conf/crontabs/crontab.store >> /tmp/crontab.zimbra 2>> $logfile); } if (isEnabled("zimbra-logger")) { detail("crontab: Adding zimbra-logger specific crontab entries"); qx(cat /opt/zimbra/conf/crontabs/crontab.logger >> /tmp/crontab.zimbra 2>> $logfile); } if (isEnabled("zimbra-mta")) { detail("crontab: Adding zimbra-mta specific crontab entries"); qx(cat /opt/zimbra/conf/crontabs/crontab.mta >> /tmp/crontab.zimbra 2>> $logfile); } detail("crontab: adding backup block"); qx(echo "# ZIMBRAEND -- DO NOT EDIT ANYTHING BETWEEN THIS LINE AND ZIMBRASTART" >> /tmp/crontab.zimbra); detail("crontab: Adding backup and custom entries to crontab."); qx(cat /tmp/crontab.zimbra.proc >> /tmp/crontab.zimbra); detail("crontab: installing new crontab"); qx(crontab -u zimbra /tmp/crontab.zimbra 2> /dev/null); if ( -x "/opt/zimbra/bin/zmschedulebackup" && scalar @backupSchedule > 0) { detail("crontab: Restoring previous backup schedule."); for (my $i=0;$i<=$#backupSchedule;$i++) { chomp($backupSchedule[$i]); if ($i == 0) { detail("crontab: $SU \"/opt/zimbra/bin/zmschedulebackup -R $backupSchedule[$i]\""); runAsZimbra("/opt/zimbra/bin/zmschedulebackup -R $backupSchedule[$i]"); } else { detail("crontab: $SU \"/opt/zimbra/bin/zmschedulebackup -A $backupSchedule[$i]\""); runAsZimbra("/opt/zimbra/bin/zmschedulebackup -A $backupSchedule[$i]"); } } } elsif ( -f "/opt/zimbra/bin/zmschedulebackup" && scalar @backupSchedule == 0 && !$newinstall && $nohsm) { detail("crontab: No backup schedule found: installing default schedule."); qx($SU "/opt/zimbra/bin/zmschedulebackup -D" >> $logfile 2>&1); } progress ("done.\n"); configLog("setupCrontab"); } sub getSystemMemory { my $os = lc qx(uname -s); chomp($os); return "unknown" unless $os; my $mem; if ($os eq "linux") { $mem = qx(cat /proc/meminfo | grep ^MemTotal: | awk '{print \$2}'); chomp($mem); $mem = sprintf "%0.1f", $mem/(1024*1024); } elsif ($os eq "darwin") { $mem = qx(sysctl hw.memsize | awk '{print \$NF}'); chomp($mem); $mem = sprintf "%0.1f", $mem/(1024*1024*1024); } return $mem; } sub mysqlMemoryPercent { my $system_mem = shift; my $os = lc qx(uname -s); chomp($os); my $percent = 30; return $percent; } sub mailboxdMemoryMB { my $system_mem = shift; my $memory; if ($system_mem > 16) { $memory = 0.2*$system_mem; } else { $memory = 0.25*$system_mem; } return int($memory*1024); } sub addServerToHostPool { progress ( "Adding $config{HOSTNAME} to zimbraMailHostPool in default COS..." ); my $id = getLdapServerValue("zimbraId", $config{HOSTNAME}); my $hp = getLdapCOSValue("zimbraMailHostPool"); if ($id eq "") { progress("failed. Couldn't find a server entry for $config{HOSTNAME}\n"); return undef; } $hp.=(($hp eq "") ? "$id" : "\n$id"); my %k; my @zmprov_args = (); foreach my $serverid (split(/\n/, $hp)) { $k{$serverid}=1; } foreach my $host (keys %k) { push(@zmprov_args, ('zimbraMailHostPool', $host)); } my $rc = setLdapCOSConfig('default', @zmprov_args); progress(($rc == 0) ? "done.\n" : "failed.\n"); } sub mainMenu { my %mm = (); $mm{createsub} = \&createMainMenu; displayMenu(\%mm); } sub stopLdap { main::progress("Stopping ldap..."); my $rc = runAsZimbra("/opt/zimbra/bin/ldap stop"); main::progress(($rc == 0) ? "done.\n" : "failed. ldap had exit status: $rc.\n"); sleep 5 unless $rc; # give it a chance to shutdown. return $rc; } sub startLdap { main::detail("Checking ldap status...."); my $rc = runAsZimbra("/opt/zimbra/bin/ldap status"); main::detail(($rc == 0) ? "already running.\n" : "not running.\n"); if ($rc) { main::progress("Checking ldap status...."); $rc = runAsZimbra ("/opt/zimbra/bin/ldap status"); main::progress(($rc == 0) ? "already running.\n" : "not running.\n"); if ($rc) { main::progress("Starting ldap..."); $rc = runAsZimbra("/opt/zimbra/bin/ldap start"); main::progress(($rc == 0) ? "done.\n" : "failed with exit code: $rc.\n"); if ($rc) { system("$SU \"/opt/zimbra/bin/ldap start 2>&1 | grep failed\""); return $rc; } } } return 0; } sub resumeConfiguration { progress ( "\n\nNote\n\n" ); progress ( "The previous configuration appears to have failed to complete\n\n"); if (askYN ("Attempt to complete configuration now?", "yes") eq "yes") { applyConfig(); } else { %configStatus = (); } } sub enableTLSv1_3 { if (isInstalled("zimbra-proxy") && isEnabled("zimbra-proxy")) { progress( "Setting zimbraReverseProxySSLProtocols..."); my $rc = main::runAsZimbra("$ZMPROV mcf +zimbraReverseProxySSLProtocols TLSv1.3"); progress(($rc == 0) ? "done.\n" : "failed.\n"); my $proxysslciphers = getLdapConfigValue("zimbraReverseProxySSLCiphers"); if ($proxysslciphers eq "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4") { progress( "Setting zimbraReverseProxySSLCiphers..."); my $rc = main::runAsZimbra("$ZMPROV mcf zimbraReverseProxySSLCiphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:TLS_AES_256_GCM_SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4'"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } } if (isInstalled("zimbra-store")) { progress( "Setting mailboxd_java_options..."); my $mailboxd_java_options=getLocalConfigRaw("mailboxd_java_options"); my $new_mailboxd_options=""; foreach my $option (split(/\s+/, $mailboxd_java_options)) { if ($option =~ /-Dhttps.protocols/) { $new_mailboxd_options .= " -Dhttps.protocols=TLSv1.2,TLSv1.3"; } elsif ($option =~ /-Djdk.tls.client.protocols/) { $new_mailboxd_options .= " -Djdk.tls.client.protocols=TLSv1.2,TLSv1.3"; } else{ $new_mailboxd_options.=" $option"; } } $new_mailboxd_options =~ s/^\s+//; my $rc = setLocalConfig("mailboxd_java_options", $new_mailboxd_options)if ($new_mailboxd_options ne ""); progress(($rc == 0) ? "done.\n" : "failed.\n"); progress( "Setting zimbra_zmjava_options..."); my $zimbra_zmjava_options=getLocalConfigRaw("zimbra_zmjava_options"); my $new_zimbra_zmjava_options=""; foreach my $option (split(/\s+/, $zimbra_zmjava_options)) { if ($option =~ /-Dhttps.protocols/) { $new_zimbra_zmjava_options .= " -Dhttps.protocols=TLSv1.2,TLSv1.3"; } elsif ($option =~ /-Djdk.tls.client.protocols/) { $new_zimbra_zmjava_options .= " -Djdk.tls.client.protocols=TLSv1.2,TLSv1.3"; } else{ $new_zimbra_zmjava_options.=" $option"; } } $new_zimbra_zmjava_options =~ s/^\s+//; my $rc = setLocalConfig("zimbra_zmjava_options", $new_zimbra_zmjava_options)if ($new_zimbra_zmjava_options ne ""); progress(($rc == 0) ? "done.\n" : "failed.\n"); } if (isInstalled("zimbra-ldap")) { progress( "Setting ldap_common_tlsciphersuite..."); my $rc = setLocalConfig("ldap_common_tlsciphersuite", "!aNULL:!eNULL:!RC4:!DES:!3DES:MEDIUM:HIGH"); progress(($rc == 0) ? "done.\n" : "failed.\n"); progress( "Setting ldap_common_tlsprotocolmin..."); my $rc = setLocalConfig("ldap_common_tlsprotocolmin", "3.3"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } if (isInstalled("zimbra-mta")) { progress( "Setting amavis_sslversion..."); my $rc = setLocalConfig("amavis_sslversion", "!TLSv1"); progress(($rc == 0) ? "done.\n" : "failed.\n"); } } sub addJDK17Options { if (isInstalled("zimbra-core")) { progress( "Setting java options..."); my $java_options=getLocalConfigRaw("mailboxd_java_options"); my $new_java_options=$java_options; if ($java_options !~ /-Djava.security.egd/) { $new_java_options = $new_java_options." -Djava.security.egd=file:/dev/./urandom"; } if ($java_options !~ /--add-opens java.base\/java.lang=ALL-UNNAMED/) { $new_java_options = $new_java_options." --add-opens java.base/java.lang=ALL-UNNAMED"; } if ($java_options !~ /-Dcom.redhat.fips=false/) { $new_java_options = $new_java_options." -Dcom.redhat.fips=false"; } $new_java_options =~ s/^\s+//; my $rc = setLocalConfig("mailboxd_java_options", $new_java_options)if ($new_java_options ne $java_options); progress(($rc == 0) ? "done.\n" : "failed.\n"); } } sub activateLicense { if (isNetwork() && isEnabled("zimbra-store")) { if (! $newinstall ) { progress ("Activating license..."); my $licensekey = getLdapConfigValue("zimbraNetworkRealtimeLicense"); if ($licensekey eq "") { chomp($licensekey = qx(cat $license_file)) if (-e $license_file); } if ($licensekey ne "") { my $rc = runAsZimbra("/opt/zimbra/bin/zmlicense -l -a $licensekey >/dev/null"); if ($rc != 0) { progress ("failed to activate license.\n"); } else { progress ("license successfully activated.\n"); } } else { progress ("license key not found.\n"); } } else { if ($config{LICENSEACTIVATIONOPTION} eq "1") { progress ("Looking for valid license to activate..."); my $licensekey = $config{LICENSEKEY}; my $rc = runAsZimbra("/opt/zimbra/bin/zmlicense -c >/dev/null"); if ($rc == 256 || $rc == 512) { my $lic = 1; if ($licensekey ne "") { $rc = runAsZimbra("/opt/zimbra/bin/zmlicense -a $licensekey >/dev/null"); if ($rc != 0) { progress ("failed to activate license.\n"); $lic = 0; } else { progress ("license successfully activated.\n"); } } else { progress ("license key not found.\n"); } if ($lic == 0){ progress ("\n*******ERROR\n\nFailed to activate a license - this will prevent your server from functioning properly\n"); progress ("Please contact Zimbra to obtain a license\n"); ask ("Press RETURN to continue",""); } } else { progress ("license already activated.\n"); } } } } } ### end subs __END__ ================================================ FILE: rpmconf/LicenseTool/Zimbra/Customer.pm ================================================ package Zimbra::Customer; sub new { my $class = shift; my $attrs = shift; my $self = {}; bless $self, $class; if (defined ($attrs)) { $self->{name} = $$attrs{name}; $self->{id} = $$attrs{id}; } return $self; } sub toText { my $self = shift; my $verbose = shift; my $txt = "ID: $self->{id}\n"; $txt .= "Name: $self->{name}\n"; return $txt; } sub display { my $self = shift; my $verbose = shift; print $self->toText($verbose); } 1; ================================================ FILE: rpmconf/LicenseTool/Zimbra/License.pm ================================================ package Zimbra::License; use strict; sub new { my $class = shift; my $attrs = shift; my $self = {}; bless $self, $class; if (defined ($attrs)) { $self->{id} = $$attrs{id}; $self->{license_text} = $$attrs{license_text}; $self->{license_version} = $$attrs{license_version}; $self->{customer_id} = $$attrs{customer_id}; $self->{expiration} = $$attrs{expiration}; $self->{is_deleted} = $$attrs{is_deleted}; foreach (keys %{$$attrs{options}}) { $self->{options}{$_} = $$attrs{options}{$_}; } } return $self; } sub toText { my $self = shift; my $verbose = shift; return ($self->licenseToText($verbose)); } sub licenseToText { my $self = shift; my $verbose = shift; my $txt = ""; if ($self->{is_deleted}) { $txt .= "THIS LICENSE IS DELETED\n"; } if ($verbose) { $txt .= $self->{license_text},"\n"; } else { $txt .= sprintf ("License ID: %d\n", $self->{id}); $txt .= sprintf ("License Version: %d\n", $self->{license_version}); $txt .= sprintf ("Customer ID: %d\n", $self->{customer_id}); $txt .= sprintf ("Expiration: %s\n", $self->{expiration}); foreach (sort keys %{$self->{options}}) { $txt .= sprintf ("OPTION: %s %s\n", $_, $self->{options}{$_}); } } return $txt; } sub generate { my $self = shift; print "Generating license..."; $self->{license_version} = Zimbra::LicenseKey::getCurrentKeyId(); $self->{license_text} = Zimbra::LicenseKey::sign($self->licenseToText())."\n".$self->licenseToText(); print "Done\n"; return 1; } sub display { my $self = shift; my $verbose = shift; print $self->toText($verbose); } sub licenseSignature { my $self = shift; my @sig = split ('\n',$self->{license_text}); my $s = ""; foreach (@sig) { if (/^$/) {last;} $s .= $_."\n"; } return $s; } sub verify { my $self = shift; my $verbose = shift; my $key = Zimbra::LicenseKey::getKey($self->{license_version}); return ($key->verify($self->licenseSignature(),$self->licenseToText())); return 0; } 1; ================================================ FILE: rpmconf/LicenseTool/Zimbra/LicenseKey.pm ================================================ package Zimbra::LicenseKey; # id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, # pubkey TEXT NOT NULL, # privkey TEXT NOT NULL, # gendate DATETIME NOT NULL, # expiredate DATETIME NOT NULL, # is_expired BOOL NOT NULL DEFAULT 0 use strict; use Time::Local; sub new { my $class = shift; my $attrs = shift; my $self = {}; bless $self, $class; $self->{is_expired} = 0; if (defined $attrs) { $self->{is_expired} = $$attrs{is_expired}; $self->{gendate} = sqlTimeToTs($$attrs{gendate}); $self->{expiredate} = sqlTimeToTs($$attrs{expiredate}); @{$self->{pubkey}} = (); foreach (split /\n/, $$attrs{pubkey}) { push @{$self->{pubkey}}, $_."\n"; } @{$self->{privkey}} = (); foreach (split /\n/, $$attrs{privkey}) { push @{$self->{privkey}}, $_."\n"; } $self->{id} = $$attrs{id}; } return $self; } sub toText { my $self = shift; my $verbose = shift; my $txt = ""; if ($self->{is_expired}) { $txt .= "KEY EXPIRED\n\n"; } $txt .= "ID: "; if (defined($self->{id})) { $txt .= $self->{id}; } else { $txt .= "NULL"; } $txt .= "\n"; $txt .= "Created: ". tsToSqlTime($self->{gendate}). "\n"; $txt .= "Expires: ". tsToSqlTime($self->{expiredate}). "\n"; if ($verbose) { $txt .= "Private Key: \n"; $txt .= "".Zimbra::LicenseKey::keyToString($self->{privkey}); $txt .= "Public Key: \n"; $txt .= "".Zimbra::LicenseKey::keyToString($self->{pubkey}); } return $txt; } sub display { my $self = shift; my $verbose = shift; print $self->toText($verbose); } sub keyToString { my $key = shift; my $rv = ""; foreach (@{$key}) { $rv .= $_; } return $rv; } sub generate { print "Generating key..."; my $self = shift; my $ed = shift; my $gd = time(); if ($ed eq "") { # default 365 days $ed = $gd + (60*60*24*365); } else { } $self->{'gendate'} = $gd; $self->{'expiredate'} = $ed; # id set when we store it # Perl Openssl seems like too much trouble... my $privtmpfile = "/tmp/key.$$.pem"; my $pubtmpfile = "/tmp/pubkey.$$.pem"; my $rc = 0xffff & system ("openssl genrsa -out $privtmpfile 2048 2> /dev/null"); $rc = $rc >> 8; if ($rc) { print "FAILED\n"; return undef; } open KEY, "$privtmpfile" or return undef; @{$self->{'privkey'}} = ; close KEY; my $rc = 0xffff & system ("openssl rsa -in $privtmpfile -pubout -out $pubtmpfile 2> /dev/null"); $rc = $rc >> 8; if ($rc) { print "FAILED\n"; return undef; } open KEY, "$pubtmpfile" or return undef; @{$self->{'pubkey'}} = ; close KEY; unlink $privtmpfile; unlink $pubtmpfile; # pubkey, privkey print "Done\n"; return 1; } sub verify { my $self = shift; my $signature = shift; my $plaintext = shift; #print "Verifying $signature\n"; #print "Against $plaintext\n"; my $tmppkfile = "/tmp/signkey.$$"; open K, "> $tmppkfile" or return undef; foreach (@{$self->{privkey}}) { print K $_; } close K; my $tmpsnfile = "/tmp/sn.$$"; open K, "> $tmpsnfile" or return undef; print K $signature; close K; my $tmp64file = "/tmp/64.$$"; open K, "> $tmp64file" or return undef; print K $plaintext; close K; my $tmpsigfile = "/tmp/sig.$$"; #print "openssl base64 -d -in $tmpsnfile -out $tmpsigfile > /dev/null 2>&1\n\n"; my $rc = 0xffff & system ("openssl base64 -d -in $tmpsnfile -out $tmpsigfile > /dev/null 2>&1"); #print "openssl dgst -prverify $tmppkfile -signature $tmpsigfile $tmp64file > /dev/null 2>&1\n\n"; my $rc = 0xffff & system ("openssl dgst -prverify $tmppkfile -signature $tmpsigfile $tmp64file > /dev/null 2>&1"); $rc = $rc >> 8; if ($rc) { return undef; } unlink $tmppkfile; unlink $tmpsnfile; unlink $tmp64file; unlink $tmpsigfile; return 1; } sub sign { my ($text) = (@_); my $key = getCurrentKey(); if (!defined ($key)) { print STDERR "No key to sign with!\n\n"; return undef; } my $tmppkfile = "/tmp/signkey.$$"; my $tmpsnfile = "/tmp/clear.$$"; my $tmp64file = "/tmp/64.$$"; open K, "> $tmppkfile" or return undef; foreach (@{$key->{privkey}}) { print K $_; } close K; open K, "> $tmpsnfile" or return undef; print K $text; close K; #print "openssl dgst -sign $tmppkfile $tmpsnfile | openssl base64 -e -out $tmp64file\n"; my $rc = 0xffff & system ("openssl dgst -sign $tmppkfile $tmpsnfile | openssl base64 -e -out $tmp64file"); $rc = $rc >> 8; if ($rc) { print "FAILED\n"; return undef; } my $signed = ""; open K, "$tmp64file" or return undef; while () { $signed .= $_; } close K; unlink $tmppkfile; unlink $tmpsnfile; unlink $tmp64file; return $signed; } sub tsToSqlTime { my $ts = shift; my $dayTrunc = shift; # 2005-09-18 04:03:33 my @tm = localtime($ts); # Truncate at hours. if (defined($dayTrunc)) { return sprintf ("%4d-%02d-%02d %02d:%02d:%02d", $tm[5]+1900,$tm[4]+1,$tm[3],0,0,0); } else { return sprintf ("%4d-%02d-%02d %02d:%02d:%02d", $tm[5]+1900,$tm[4]+1,$tm[3],$tm[2],0,0); } } sub sqlTimeToTs { my $sqlTime = shift; # 2005-09-18 04:03:33 return timelocal(substr($sqlTime,17,2),substr($sqlTime,14,2), substr($sqlTime,11,2),substr($sqlTime,8,2), (substr($sqlTime,5,2)-1),substr($sqlTime,0,4)); } 1; ================================================ FILE: rpmconf/LicenseTool/Zimbra/LicensingDB.pm ================================================ package Zimbra::LicensingDB; use strict; use DBI; use Time::Local; #my $data_source="dbi:mysql:database=license;mysql_read_default_file=/opt/zimbra/conf/my.logger.cnf;mysql_socket=/opt/zimbra/logger/db/mysql.sock"; my $data_source="dbi:mysql:database=license;mysql_read_default_file=/etc/my.cnf;mysql_socket=/var/lib/mysql/mysql.sock"; my $username="license"; my $password = "licensing"; my $dbh = DBI->connect($data_source, $username, $password, {PrintError=>0}); if (!$dbh) { print STDERR "DB: Can't connect to $data_source: $DBI::errstr\n"; exit 1; } sub tsToSqlTime { my $ts = shift; my $dayTrunc = shift; # 2005-09-18 04:03:33 my @tm = localtime($ts); # Truncate at hours. if (defined($dayTrunc)) { return sprintf ("%4d-%02d-%02d %02d:%02d:%02d", $tm[5]+1900,$tm[4]+1,$tm[3],0,0,0); } else { return sprintf ("%4d-%02d-%02d %02d:%02d:%02d", $tm[5]+1900,$tm[4]+1,$tm[3],$tm[2],0,0); } } sub sqlTimeToTs { my $sqlTime = shift; # 2005-09-18 04:03:33 return timelocal(substr($sqlTime,17,2),substr($sqlTime,14,2), substr($sqlTime,11,2),substr($sqlTime,8,2), (substr($sqlTime,5,2)-1),substr($sqlTime,0,4)); } sub getCustomer { my $id = shift; my $statement = "select id, name from customer where id=\"$id\""; my $customer = $dbh->selectrow_hashref($statement); if (defined($customer)) { return $customer; } else { return undef; } } sub putCustomer { my $customer = shift; my $statement = "insert into customer (name) values (?)"; my $sth = sqlExec ($statement, $customer->{name}); if (!$sth) { return undef; } my $h = $dbh->selectrow_hashref("select max(id) as id from customer"); my $id = $h->{id}; return $id; } sub getKeyIds { my $statement = "select id from sign_keys"; my $ids = $dbh->selectall_arrayref($statement); return $ids; } sub getCustomerIds { my $statement = "select id from customer"; my $ids = $dbh->selectall_arrayref($statement); return $ids; } sub getKey { my $id = shift; my $statement = "select id, pubkey, privkey, gendate, expiredate, is_expired ". "from sign_keys where id=\"$id\""; my $key = $dbh->selectrow_hashref($statement); if (defined($key)) { return $key; } else { return undef; } } sub putKey { my $key = shift; my $statement = "insert into sign_keys (pubkey, privkey, gendate, expiredate, is_expired) ". "values (?,?,?,?,?)"; my $sth = sqlExec ($statement, Zimbra::LicenseKey::keyToString($key->{pubkey}), Zimbra::LicenseKey::keyToString($key->{privkey}), tsToSqlTime($key->{gendate}), tsToSqlTime($key->{expiredate}), $key->{is_expired}); my $h = $dbh->selectrow_hashref("select max(id) as id from sign_keys"); my $id = $h->{id}; return $id; } sub getLicenseIds { my $statement = "select id from customer_license"; my $ids = $dbh->selectall_arrayref($statement); return $ids; } sub getLicense { my $id = shift; my $statement = "select id, expiration, customer_id, license_text, license_version, is_deleted ". "from customer_license where id=\"$id\""; my $license = $dbh->selectrow_hashref($statement); if (!defined($license)) { return undef; } $statement = "select name, value from license_details where license_id=\"$id\""; my $ary = $dbh->selectall_arrayref($statement); foreach my $row (@$ary) { #print "$$row[0] == $$row[1]\n"; $license->{options}{$$row[0]} = $$row[1]; } return $license; } sub updateLicense { my $license = shift; my $statement = "update customer_license set customer_id=\"$license->{customer_id}\", ". "expiration=\"$license->{expiration}\", ". "license_text=\'$license->{license_text}\', ". "license_version=\"$license->{license_version}\", ". "is_deleted=\"$license->{is_deleted}\" ". "where id=\"$license->{id}\""; my $sth = sqlExec ($statement); if (!$sth) { return undef; } $statement = "delete from license_details where license_id=\"$license->{id}\""; my $sth = sqlExec ($statement); if (!$sth) { return undef; } $statement = "insert into license_details (license_id, name, value) values (?,?,?)"; foreach (sort keys %{$license->{options}}) { $sth = sqlExec ($statement, $license->{id}, $_, $license->{options}{$_}); if (!$sth) { return undef; } } return 1; } sub putLicense { my $license = shift; my $statement = "insert into customer_license (customer_id, expiration, license_text, license_version) ". "values (?,?,?,?)"; my $sth = sqlExec ($statement, $license->{customer_id}, $license->{expiration}, $license->{license_text}, $license->{license_version}); if (!$sth) { return undef; } my $h = $dbh->selectrow_hashref("select max(id) as id from customer_license"); my $id = $h->{id}; return $id; $statement = "insert into license_details (license_id, name, value) values (?,?,?)"; foreach (sort keys %{$license->{options}}) { $sth = sqlExec ($statement, $license->{id}, $_, $license->{options}{$_}); if (!$sth) { return undef; } } } sub sqlExec { my $statement = shift; my @args = @_; my $sth = $dbh->prepare($statement); #print "Executing $statement with @args\n\n"; eval { if (!$sth->execute(@args) ) { die $sth->errstr; } }; if ($@) { print "Error executing $statement with @args\n"; print $sth->errstr,"\n"; print "$@\n"; return undef; } return $sth; } 1; ================================================ FILE: rpmconf/LicenseTool/db/create_license_db.sql ================================================ DROP DATABASE IF EXISTS license; CREATE DATABASE license; USE license; GRANT ALL ON license.* to 'license' IDENTIFIED BY 'licensing'; GRANT ALL ON license.* to 'license'@'localhost' IDENTIFIED BY 'licensing'; # Customers CREATE TABLE customer ( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, UNIQUE INDEX i_name (name(100)) ); # Foreign keys (SF id, etc) CREATE TABLE fk ( customer_id VARCHAR(255) NOT NULL, fk VARCHAR(255) NOT NULL, comment VARCHAR(255), PRIMARY KEY (customer_id(100), fk(100)) ); # Keys CREATE TABLE sign_keys ( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, pubkey TEXT NOT NULL, privkey TEXT NOT NULL, gendate DATETIME NOT NULL, expiredate DATETIME NOT NULL, is_expired BOOL NOT NULL DEFAULT 0 ); # Licenses CREATE TABLE customer_license ( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, expiration DATETIME NOT NULL, customer_id VARCHAR(255) NOT NULL, license_text TEXT, license_version INT UNSIGNED NOT NULL, is_deleted BOOL NOT NULL DEFAULT 0 ); # License Details CREATE TABLE license_details ( license_id INT NOT NULL, name VARCHAR(64) NOT NULL, value VARCHAR(255) NOT NULL ); # License info # # Customer Name # Customer ID # License ID # # Required fields # Key ID # Generation date # Expiration date # ================================================ FILE: rpmconf/LicenseTool/zmlicensetool.pl ================================================ #!/usr/bin/perl use strict; use Zimbra::LicensingDB; use Zimbra::License; use Zimbra::LicenseKey; use Zimbra::Customer; use Getopt::Long; my %options = (); my %license_options = (); my %actions = ( 'license_modify' => \&modifyLicense, 'license_verify' => \&verifyLicense, 'license_display' => \&displayLicense, 'license_create' => \&createLicense, 'license_list' => \&listLicenses, 'key_delete' => \&deleteKey, 'key_display' => \&displayKey, 'key_create' => \&createKey, 'key_list' => \&listKeys, 'customer_modify' => \&modifyCustomer, 'customer_display' => \&displayCustomer, 'customer_create' => \&createCustomer, 'customer_list' => \&listCustomers, ); GetOptions ( 'help|h|?' => \$options{'help'}, 'verbose' => \$options{'verbose'}, 'id=s' => \$options{'id'}, 'display' => sub { $options{'opt'} = 'display' }, 'create' => sub { $options{'opt'} = 'create' }, 'list' => sub { $options{'opt'} = 'list' }, 'verify' => sub { $options{'opt'} = 'verify' }, 'modify' => sub { $options{'opt'} = 'modify' }, 'delete' => sub { $options{'opt'} = 'delete' }, 'key' => sub { $options{'action'} = 'key' }, 'license' => sub { $options{'action'} = 'license' }, 'customer' => sub { $options{'action'} = 'customer' }, 'expiration=s' => \$options{'expiration'}, 'name=s' => \$options{'name'}, "opt=s" => \%license_options, ); setAction($options{'action'}, $options{'opt'}); if (defined ($options{'help'}) ) { usage(); } if (!defined ($actions{$options{'action'}})) { usage("Unknown command $options{'action'}"); } &{$actions{$options{'action'}}}(); sub setAction { my $act = shift; my $opt = shift; $options{'action'} = "${act}_${opt}"; if (!defined ($actions{$options{'action'}})) { usage("Unknown command $act"); } } sub displayCurrentKey { my $key = getCurrentKey(); if (!defined($key)) { die "Can't get current key\n"; } $key->display($options{'verbose'}); } sub displayKey { if (!defined ($options{'id'}) ) { usage ("No key specified!"); } if ($options{'id'} =~ /current/i) {return displayCurrentKey()}; my $key = getKey($options{'id'}); if (!defined($key)) { die "Can't get key $options{'id'}\n"; } $key->display($options{'verbose'}); } sub createKey { my %attrs = (); my $key = new Zimbra::LicenseKey; if (!$key->generate()) { exit 1; } if (!putKey($key)) { exit 1; } $key->display($options{'verbose'}); } sub listKeys { my $ids = getKeyIds(); foreach (@$ids) { my $key = getKey($$_[0]); if (!defined($key)) { warn "Can't get key $$_[0]\n"; } $key->display($options{'verbose'}); } } sub verifyLicense { if (!defined($options{'id'})) { usage ("Missing license id"); } my $license = getLicense($options{'id'}); if (!defined($license)) { usage ("Can't get license $options{'id'}\n"); } if ($license->verify($options{'verbose'})) { print "License verified\n"; exit 0; } else { print "Verification FAILED\n"; exit 1; } } sub displayLicense { if (!defined($options{'id'})) { usage ("Missing license id"); } my $license = getLicense($options{'id'}); if (!defined($license)) { usage ("Can't get license $options{'id'}\n"); } $license->display($options{'verbose'}); } sub createLicense { if (!defined($options{'id'})) { usage ("Missing customer id"); } if (!defined($options{'expiration'})) { usage ("Missing license expiration"); } $options{'expiration'} = "$options{'expiration'} 00:00:00"; my $customer = getCustomer($options{id}); if (!defined ($customer)) { usage ("Customer $options{id} not found!"); } my $license = new Zimbra::License(); if (!defined ($license)) { usage(); } $license->{'customer_id'} = $customer->{'id'}; $license->{'expiration'} = $options{'expiration'}; $license->{license_version} = getCurrentKeyId(); foreach (sort keys %license_options) { $license->{options}{$_} = $license_options{$_}; } my $id = putLicense($license); if (!$id) { usage ("License creation failed"); } if (!$license->generate()) { usage ("License generation failed!"); } if (!updateLicense($license)) { usage ("License generation failed!"); } $license->display($options{'verbose'}); } sub createCustomer { if (!defined($options{'name'})) { usage ("Missing customer name"); } my $customer = new Zimbra::Customer(); $customer->{name} = $options{'name'}; if (defined($customer)) { my $id = putCustomer($customer); if ($id) { $customer->display($options{'verbose'}); } } } sub displayCustomer { if (!defined ($options{'id'}) ) { usage ("No customer specified!"); } my $customer = getCustomer($options{'id'}); if (defined($customer)) { $customer->display($options{'verbose'}); } } sub listCustomers { my $ids = getCustomerIds(); foreach (@$ids) { my $customer = getCustomer($$_[0]); if (!defined($customer)) { warn "Can't get customer $$_[0]\n"; } $customer->display($options{'verbose'}); } } sub listLicenses { my $ids = getLicenseIds(); foreach (@$ids) { my $license = getLicense($$_[0]); if (!defined($license)) { warn "Can't get license $$_[0]\n"; } $license->display($options{'verbose'}); } } sub modifyLicense { if (!defined($options{'id'})) { usage ("Missing license id"); } my $customer; my $license = getLicense($options{'id'}); if (!defined($license)) { usage ("Can't get license $options{'id'}\n"); } if (defined ($options{'expiration'})) { $license->{'expiration'} = $options{'expiration'}." 00:00:00"; } if (defined ($license_options{'customer'})) { $customer = getCustomer($license_options{'customer'}); if (!defined($customer)) { usage ("Can't get customer $license_options{'customer'}\n"); } $license->{'customer_id'} = $customer->{'id'}; delete $license_options{'customer'}; } if (defined ($license_options{'is_deleted'})) { $license->{'is_deleted'} = $license_options{'is_deleted'}; delete $license_options{'is_deleted'}; } foreach (keys %license_options) { $license->{options}{$_} = $license_options{$_}; } if (!$license->generate()) { usage ("License generation failed!"); } if (!updateLicense($license)) { usage ("License generation failed!"); } $license->display($options{'verbose'}); } sub usage { my $msg = shift; print STDERR $msg; print STDERR "\n"; print STDERR< [--verbose] Command is one of: --key key operations key subcommands: --list list keys --create create key --delete delete key --display --id display key --customer customer operations --list list customers --create --name create customer --display --id display customer --license license operations --list list licenses --display --id display license --verify --id verify license --create create license --create --id --expiration [--opt key=val] --modify --modify --id [--expiration ] [--opt key=val] EOF exit 1; } ## Db Access commands sub getCustomerIds { my $ids = Zimbra::LicensingDB::getCustomerIds(); return $ids; } sub getCustomer { my $id = shift; #print "Fetching customer $id from database..."; my $attrs = Zimbra::LicensingDB::getCustomer($id); if (defined ($attrs)) { my $customer = new Zimbra::Customer($attrs); #print "Done\n"; return $customer; } #print "FAILED\n"; return undef; } sub putCustomer { my $customer = shift; #print "Storing customer $self->{name} in database..."; $customer->{id} = Zimbra::LicensingDB::putCustomer($customer); if (defined($customer->{id})) { #print "Customer ID $customer->{id}...Done\n"; return 1; } #print "FAILED\n"; return undef; } sub getCurrentKeyId { my $ids = getKeyIds(); if ($#$ids < 0) {return undef;} my $curId = $$ids[$#$ids][0]; return $curId; } sub getCurrentKey { my $id = getCurrentKeyId; if (!defined ($id)) { return undef; } return (getKey($id)); } sub getKeyIds { my $ids = Zimbra::LicensingDB::getKeyIds(); return $ids; } sub getKey { my $keyId = shift; #print "Fetching key $keyId from database..."; my $attrs = Zimbra::LicensingDB::getKey($keyId); if (defined ($attrs)) { my $key = new Zimbra::LicenseKey($attrs); #print "Done\n"; return $key; } #print "FAILED\n"; return undef; } sub putKey { my $key = shift; #print "Storing key in database..."; $key->{id} = Zimbra::LicensingDB::putKey($key); if (defined($key->{id})) { #print "Key ID $key->{id}...Done\n"; return 1; } #print "FAILED\n"; return undef; } sub getLicenseIds { my $ids = Zimbra::LicensingDB::getLicenseIds(); return $ids; } sub getLicense { my $id = shift; my $attrs = Zimbra::LicensingDB::getLicense($id); if (defined($attrs)) { my $license = new Zimbra::License($attrs); return $license; } return undef; } sub putLicense { my $license = shift; #print "Storing license in database..."; $license->{id} = Zimbra::LicensingDB::putLicense($license); if (defined($license->{id})) { #print "License ID $license->{id}...Done\n"; return 1; } #print "FAILED\n"; return undef; } sub updateLicense { my $license = shift; #print "Storing license in database..."; if (Zimbra::LicensingDB::updateLicense($license)) { return 1; } #print "FAILED\n"; return undef; } ================================================ FILE: rpmconf/Patch/bin/zmpatch.pl ================================================ #!/usr/bin/perl -w # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # use strict; use lib qw(/opt/zimbra/common/lib/perl5 lib corebuild/opt/zimbra/zimbramon/lib); use Zimbra::Util::Common; use XML::SAX; use XML::Simple; use Data::Dumper; use Getopt::Long; use File::Path; use File::Copy; use File::Basename; use Time::localtime qw(ctime); my %options = (); sub getDateStamp(); sub progress($$$); sub detail($); sub debugLog($); sub getInstalledVersion(); sub getInstalledType(); sub usage; sub doPatchBuild(); sub doPatchDeploy(); sub doIncrementJSVersion(); GetOptions ("config=s" => \$options{config}, "verbose|v+" => \$options{verbose}, "debug|d+" => \$options{debug}, "help" => sub { usage(); }, "dryrun|n" => \$options{dryrun}, "force" => \$options{force}, "build|b" => \$options{build}, "source=s" => \$options{build_source}, "target=s" => \$options{build_target}, "version=s" => \$options{build_version}); ($>) and usage() unless $options{build}; my $progName = "zmpatch"; my $patchBuildNumber; my %versionInfo; my ($platform, $zmtype, $config); $options{verbose} = 0 unless $options{verbose}; if ($options{build}) { usage() unless ($options{build_source} && $options{build_version}); $options{build_target}="$options{build_source}/ZimbraBuild/zcs-patch-$options{build_version}" unless $options{build_target}; } my $logfile; if($options{build_source}) { $logfile = "$options{build_source}/logs/${progName}.".getDateStamp().".log"; } else { $logfile = "/tmp/${progName}.".getDateStamp().".log"; } open LOGFILE, ">$logfile" or die "Can't open $logfile: $!\n"; if($options{build_source}) { unlink("$options{build_source}/log/${progName}.log") if (-e "$options{build_source}/log/${progName}.log"); symlink($logfile, "$options{build_source}/log/${progName}.log"); } else { unlink("/tmp/${progName}.log") if (-e "/tmp/${progName}.log"); symlink($logfile, "/tmp/${progName}.log"); } if ($options{build}) { if (-f "$options{build_source}/ZimbraBuild/RE/BUILD") { open(BUILD, "$options{build_source}/ZimbraBuild/RE/BUILD"); } else { progress("Unable to determine build number.\n", 0, 0); exit 1; } } else { $zmtype=getInstalledType(); debugLog("Install type: $zmtype\n"); unless (-x "/opt/zimbra/libexec/get_plat_tag.sh") { print "ZCS Install not found.\n"; exit 1; } $platform = qx(/opt/zimbra/libexec/get_plat_tag.sh); chomp($platform); if (-f "source/build") { open(BUILD, "source/build"); } else { progress("Unable to determine build number.\n", 0, 0); exit 1; } } $patchBuildNumber = ; chomp($patchBuildNumber); close(BUILD); unless ($options{config} && -f $options{config}) { progress("Missing config file.\n", 0, 0); usage(); exit 1; } if ($options{config} && -f $options{config}) { $config = XMLin($options{config}, ForceArray => [ 'name', 'patch', 'package', 'file', 'deletefile', 'zimlet','target', 'preinstall', 'postinstall'], KeyAttr => [ 'name', 'patch', 'package', 'source', 'version', 'postinstall', 'preinstall' ], SuppressEmpty => 1); my $debug_text = Dumper($config); debugLog($debug_text); } doPatchBuild() if ($options{build}); doPatchDeploy(); close(LOGFILE); exit(0); ################################################################ # Subroutines ################################################################ sub initPatchDir() { my $bin_dir=$options{build_target}."/bin"; my $conf_dir=$options{build_target}."/conf"; my $src_dir=$options{build_target}."/source"; make_path($bin_dir); make_path($conf_dir); make_path($src_dir); copy("$options{build_source}/ZimbraBuild/rpmconf/Patch/bin/zmpatch.pl", $bin_dir); copy("$options{build_source}/ZimbraBuild/rpmconf/Patch/conf/zmpatch.xml", $conf_dir); copy("$options{build_source}/ZimbraBuild/rpmconf/Patch/installPatch.sh", $options{build_target}); system("chmod 755 $options{build_target}/installPatch.sh"); open(B, ">${src_dir}/build"); print B "$patchBuildNumber\n"; close(B); } sub doPatchBuild() { progress("Building patch for release $options{build_version} in $options{build_target}\n", 0, 0); initPatchDir(); my $buildStatus=0; foreach my $patch (keys %{$config->{patch}}) { progress("$config->{patch}->{$patch}->{version}\n",1,1); my $patchName=$config->{patch}->{$patch}->{version}; foreach my $package (keys %{$config->{patch}->{$patch}->{package}}) { my $pref = $config->{patch}->{$patch}->{package}->{$package}; progress("$package\n",2,1); foreach my $zimlet (keys %{$pref->{zimlet}}) { my $zref = $pref->{zimlet}->{$zimlet}; progress("$zref->{target}[0]\n", 3,1); my $zpath="$options{build_target}/source/$patchName/$package/" . dirname($zref->{target}[0]); unless (make_path($zpath)) { progress("Failed to make_path $zpath.\n",3,0); $buildStatus++; next; } my $source="$options{build_source}/$zimlet"; if (-f $source) { copy($source,$zpath); } else { progress("Failed to copy $source\n",3,0); $buildStatus++; } } foreach my $file (keys %{$pref->{file}}) { my $fref=$pref->{file}->{$file}; foreach my $target (@{$fref->{target}}) { my $fpath="$options{build_target}/source/$patchName/$package/" . dirname($target); progress("$target\n",3,1); unless (make_path($fpath)) { progress("Failed to make_path $fpath.\n",3,0); $buildStatus++; next; } my $source="$options{build_source}/$file"; if (-f $source) { copy($source,$fpath); } else { progress("Failed to copy $source\n",3,0); $buildStatus++; } } } # future #foreach my $file (keys %{$pref->{dir}}) { #print "$file\n"; #} } } if(!$buildStatus) { # Clean up zmpatch files on successful build unlink("$logfile"); unlink("/tmp/${progName}.log"); } exit($buildStatus); } sub doPatchDeploy() { getInstalledVersion(); my $currentRelease = getReleaseString($versionInfo{current}); my $currentBuild = getVersionComponent($versionInfo{current},"build"); progress("Current Version: $versionInfo{current}\n", 0, 1); if ($currentBuild > $patchBuildNumber) { progress("Current install $currentRelease is newer than patch version.\n", 0, 1); return undef; } if ($currentBuild == $patchBuildNumber && !$options{force}) { progress("Current install $currentRelease is the same as patch version.\n", 0, 1); return undef; } while () { if ($config->{patch}->{$currentRelease}) { print "Found Patch for $currentRelease called $config->{patch}->{$currentRelease}->{version}\n"; deployPatch($currentRelease); $currentRelease = $config->{patch}->{$currentRelease}->{version}; } else { last; } } } sub deployPatch($) { my ($v) = @_; progress("Deploying patch for $v\n",1,1); my $currentBuild=getVersionComponent($versionInfo{current},"build"); my $currentRelease = getReleaseString($versionInfo{current}); my $patch = $config->{patch}->{$v}; # check the build number range for validity my $min = $patch->{buildnum}->{min}; my $max = $patch->{buildnum}->{max}; if (defined($min) && $currentBuild < $min) { progress("Current install build is too low is not patchabled.\n",1,0); progress("Min: $min Max: $max Current: $currentBuild\n",1,1); return undef; } if (defined($max) && $currentBuild > $max) { progress("Patch can not be applied. Current build $currentBuild exceeds max build value $max for patch.\n",1,0); progress("Min: $min Max: $max Current: $currentBuild\n",1,1); return undef; } # log an install session start logSession("INSTALL SESSION START"); # force this so the build number is always updated # not all patches will have zimbra-core components logSession("UPGRADED zimbra-core-${currentRelease}_${patchBuildNumber}"); # do preinstall tasks # loop through each package foreach my $package (keys %{$patch->{package}}) { # make sure package is installed my $pref = $patch->{package}->{$package}; next unless (isInstalled($package)); # deploy the zimlets foreach my $zimlet (keys %{$pref->{zimlet}}) { my $zref = $pref->{zimlet}->{$zimlet}; my $ztype = ""; if (defined $zref->{type}) { $ztype = lc($zref->{type}); } next if ($zmtype eq "FOSS" && $ztype eq "network"); my $zimletname=basename($zref->{target}[0]); $zimletname =~ s/\.zip//; progress("$zimletname...",2,1); my $srcfile="./source/$patch->{version}/$package/$zref->{target}[0]"; my $dstfile=$zref->{target}[0]; if (-f "$srcfile") { debugLog("cp $srcfile $dstfile"); copy($srcfile, $dstfile) unless $options{dryrun}; } else { progress("skipped. No such file $srcfile.\n",0,1); } unless ($options{dryrun}) { if (lc($zref->{deploy}) eq "true") { my $rc; progress("deployed...",0,1) unless (runAsZimbra("zmzimletctl -l deploy $dstfile")); runAsZimbra("zmprov flushcache zimlet") if (lc($zref->{flushcache}) eq "true"); } } progress("updated.\n", 0, 1); } progress("Updating files for package $package\n", 1, 0); # deploy the files foreach my $file (keys %{$pref->{file}}) { my $fref = $pref->{file}->{$file}; my $ftype = ""; if (defined $fref->{type}) { $ftype = lc($fref->{type}); } next if ($zmtype eq "FOSS" && $ftype eq "network"); foreach my $dstfile (@{$fref->{target}}) { progress("$dstfile...",2,1); my $srcfile="./source/$patch->{version}/$package/$dstfile"; unless (-f "$srcfile") { progress("No such source file $srcfile\n",0,1); next; } debugLog("cp $srcfile $dstfile"); copy($srcfile, $dstfile) unless $options{dryrun}; # verify the perms/ownershiA my ($owner,$group,$mode); unless ($options{dryrun}) { chown($owner,$dstfile) if ($owner = $fref->{perms}->{owner}); system("chgrp $group $dstfile") if ($group = $fref->{perms}->{group}); system("chmod $mode $dstfile") if ($mode = $fref->{perms}->{mode}); } progress("copied.\n", 1, 1); } } # Delete files if necessary foreach my $deleteFile ($pref->{deletefile}) { foreach my $dhash (@{$deleteFile}) { foreach my $dstfile (@{$dhash->{target}}) { progress("$dstfile...",2,1); debugLog("rm $dstfile"); unlink($dstfile) unless $options{dryrun}; progress("deleted.\n", 1, 1); } } } # update the installed version of package if ($package eq "zimbra-store") { &doIncrementJSVersion(); } logSession("UPGRADED $package-${currentRelease}_${patchBuildNumber}") unless ($package eq "zimbra-core"); } # do postinstall tasks foreach my $task (@{$patch->{postinstall}}) { progress("Running $task...",1,0); if (runAsZimbra($task)) { progress("failed.\n",1,0); } else { progress("done.\n",1,0); } } # log an install session complete logSession("INSTALL SESSION COMPLETE"); logSession("CONFIG SESSION START"); logSession("CONFIGURED BEGIN"); logSession("CONFIGURED patch$patch->{version}"); logSession("CONFIGURED END"); logSession("CONFIG SESSION COMPLETE"); } sub logSession($) { my ($msg) = @_; return if $options{dryrun}; my $date = qx(date +%s); chomp($date); open(SESS, ">>/opt/zimbra/.install_history"); print SESS "$date: $msg\n"; close(SESS); } sub runAsZimbra { my $cmd = shift; my $SU = "su - zimbra -c "; detail ( "*** Running as zimbra user: $cmd\n" ); my $rc; $rc = 0xffff & system("$SU \"$cmd\" >> $logfile 2>&1"); return $rc; } sub make_path($) { my ($dir) = @_; eval { mkpath($dir) }; debugLog("Couldn't create $dir: $@") if ($@); return (($@) ? undef : 1); } sub debugLog($) { print "@_\n" if $options{debug}; } sub usage { ($>) and print STDERR "Warning: $0 must be run as root!\n\n"; print STDERR "Usage: $0 [-h] -c -build\n"; print STDERR "\t--help|-h: display this help message\n"; print STDERR "\t--config|-c : patch configuration file.\n"; print STDERR "\t--verbose|-v: verbose output.\n"; print STDERR "\t--debug|-d: debug output.\n"; print STDERR "\t--dryrun|-n: patch dryrun does not apply changes.\n\n"; print STDERR " Developer Use Only\n"; print STDERR "\t--build|-b: build patch from source.\n"; print STDERR "\t--source : path to patch source.\n"; print STDERR "\t--target : destination path for patch.\n"; print STDERR "\t--version : target version of patch.\n\n"; exit 1; } sub detail($) { my $msg = shift; my ($sub,$line) = (caller(1))[3,2]; my $date = ctime(); $msg =~ s/\n$//; $msg = "$sub:$line $msg" if $options{debug}; open(LOG, ">>$logfile"); print LOG "$date $msg\n"; close(LOG); #qx(echo "$date $msg" >> $logfile); } sub progress($$$) { my ($msg,$lvl,$verbosity) = @_; $lvl=0 unless $lvl; $verbosity=0 unless $verbosity; #print "$msg lvl: $lvl verbosity: $verbosity opt_verbose: $options{verbose}\n"; print " "x$lvl. "$msg" if ($options{verbose} >= $verbosity); my ($sub,$line) = (caller(1))[3,2]; $msg = "$sub:$line $msg" if $options{debug}; detail ($msg); } sub getDateStamp() { my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time()); $year = 1900+$year; $sec = sprintf("%02d", $sec); $min = sprintf("%02d", $min); $hour = sprintf("%02d", $hour); $mday = sprintf("%02d", $mday); $mon = sprintf("%02d", $mon+1); my $stamp = "$mon$mday$year-$hour$min$sec"; return $stamp; } sub getInstalledVersion() { my %configStatus; my %installStatus; if (open H, "/opt/zimbra/.install_history") { my @history = ; close H; foreach my $h (@history) { next if ($h =~ /CONFIG SESSION COMPLETE/); if ($h =~ /CONFIG SESSION START/) { %configStatus = (); next; } next if ($h =~ /INSTALL SESSION COMPLETE/); if ($h =~ /INSTALL SESSION START/) { %installStatus = (); %configStatus = (); next; } my ($d, $op, $stage) = split ' ', $h; if ($op eq "INSTALLED" || $op eq "UPGRADED") { my $v = $stage; $stage =~ s/[-_]\d.*//; if ($stage eq "zimbra-core") { $v =~ s/_HEAD.*//; $v =~ s/^zimbra-core[-_]//; if ($v =~ /\.deb$/) { my $orig_v=$v; $v =~ s/^(\d+\.\d+\.\d+\.\w+\.\w+)\..*/$1/; $v = reverse($v); $v =~ s/\./_/; $v =~ s/\./_/; $v = reverse($v); if ($v =~ /\_deb$/) { $v = $orig_v; $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/$1/; } } else { $v =~ s/^(\d+\.\d+\.[^_]*_[^_]+_[^.]+).*/$1/; } $versionInfo{current} = $v; } } elsif ($op eq "CONFIGURED") { if ($stage eq "END") { $versionInfo{previous} = $versionInfo{current}; } } } } progress("Previous version: $versionInfo{previous}\n",0,2); progress("Current version: $versionInfo{current}\n",0,2); return $versionInfo{current}; } sub getInstalledType() { return ((-f "/opt/zimbra/bin/zmbackupquery") ? "NETWORK" : "FOSS"); } sub getReleaseString($) { my ($version) = @_; my ($major,$minor,$micro,$stage,$build) = $version =~ /(\d+)\.(\d+)\.(\d+)_([^_]*)_(\d+)/; return "${major}.${minor}.${micro}_${stage}"; } sub getVersionComponent($$) { my ($version, $component) = @_; my ($major,$minor,$micro,$stage,$build) = $version =~ /(\d+)\.(\d+)\.(\d+)_([^_]*)_(\d+)/; return $major if ($component eq "major"); return $minor if ($component eq "minor"); return $micro if ($component eq "micro"); return $stage if ($component eq "stage"); return $build if ($component eq "build"); } sub isInstalled { my $pkg = shift; my $pkgQuery; my $good = 0; if ($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) { $pkgQuery = "dpkg -s $pkg"; } else { $pkgQuery = "rpm -q $pkg"; } my $rc = 0xffff & system ("$pkgQuery > /dev/null 2>&1"); $rc >>= 8; if (($platform =~ /^DEBIAN/ || $platform =~ /^UBUNTU/) && $rc == 0 ) { $good = 1; $pkgQuery = "dpkg -s $pkg | egrep '^Status: ' | grep 'not-installed'"; $rc = 0xffff & system ("$pkgQuery > /dev/null 2>&1"); $rc >>= 8; return ($rc == $good); } else { return ($rc == $good); } } sub doIncrementJSVersion() { my $infile="/opt/zimbra/jetty/etc/zimbra.web.xml.in"; my $outfile="/opt/zimbra/data/tmp/zimbra.web.xml.in.new"; unlink("$outfile") if (-e "$outfile"); open (IN, "<$infile"); open (OUT, ">$outfile"); my $next=0; while () { if ($next == 0) { if ($_ =~ m/jsVersion<\/param-name>/) { $next = 1; } print OUT $_; } else { my ($oldVersion) = $_ =~ /(\d+)<\/param-value>/; my $newVersion=$oldVersion+1; $_ =~ s/$oldVersion/$newVersion/; print OUT $_; $next = 0; } } close(IN); close(OUT); copy($outfile, $infile); $infile="/opt/zimbra/jetty/etc/zimbraAdmin.web.xml.in"; $outfile="/opt/zimbra/data/tmp/zimbraAdmin.web.xml.in.new"; unlink("$outfile") if (-e "$outfile"); open (IN, "<$infile"); open (OUT, ">$outfile"); $next=0; while () { if ($next == 0) { if ($_ =~ m/jsVersion<\/param-name>/) { $next = 1; } print OUT $_; } else { my ($oldVersion) = $_ =~ /(\d+)<\/param-value>/; my $newVersion=$oldVersion+1; $_ =~ s/$oldVersion/$newVersion/; print OUT $_; $next = 0; } } close(IN); close(OUT); copy($outfile, $infile); } ================================================ FILE: rpmconf/Patch/conf/zmpatch.xml ================================================ Patch 7.1.1_P4 57891 58733 60364 60379 60403 60600 60632 60743 60748 60951 60952 61209 61217 61247 61509 61548 61634 61647 61763 ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbracommon.jar /opt/zimbra/lib/jars/zimbracommon.jar ZimbraBuild/corebuild/opt/zimbra/libexec/zmfixperms /opt/zimbra/libexec/zmfixperms ZimbraBuild/corebuild/opt/zimbra/bin/zmconfigdctl /opt/zimbra/bin/zmconfigdctl ZimbraBuild/corebuild/opt/zimbra/zimbramon/pylibs/state.py /opt/zimbra/zimbramon/pylibs/state.py ZimbraBuild/corebuild/opt/zimbra/lib/jars/jython-2.5.2.jar /opt/zimbra/lib/jars/jython-2.5.2.jar /opt/zimbra/lib/jars/jython-2.5.1.jar ZimbraBuild/corebuild/opt/zimbra/lib/jars/zimbrastore.jar /opt/zimbra/jetty/webapps/service/WEB-INF/lib/zimbrastore.jar /opt/zimbra/jetty/webapps/zimbra/WEB-INF/lib/zimbrastore.jar /opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/lib/zimbrastore.jar /opt/zimbra/lib/jars/zimbrastore.jar ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js /opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/Admin_all.js.zgz /opt/zimbra/jetty/webapps/zimbraAdmin/js/Admin_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties /opt/zimbra/jetty/webapps/zimbraAdmin/WEB-INF/classes/messages/ZaMsg.properties ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js /opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/EmailAddr_FormItem.js ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js /opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/common/ZaOverviewPanelController.js ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js /opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/controller/ZaDomainListController.js ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js /opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/domains/model/ZaDomain.js ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js /opt/zimbra/jetty/webapps/zimbraAdmin/js/zimbraAdmin/search/model/ZaSearch.js ZimbraBuild/storebuild/opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar /opt/zimbra/lib/ext/zimbrasync/zimbrasync.jar ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz /opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_1_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz /opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Mail_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz /opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_1_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz /opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow_2_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/CalendarAppt_all.js.zgz /opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/CalendarAppt_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/lib/ext/network/zimbranetwork.jar /opt/zimbra/lib/ext/network/zimbranetwork.jar ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/common/lib/zimbracommon.jar /opt/zimbra/jetty/common/lib/zimbracommon.jar ZimbraBuild/storebuild/opt/zimbra/lib/ext/backup/zimbrabackup.jar /opt/zimbra/lib/ext/backup/zimbrabackup.jar ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/m/mocompose /opt/zimbra/jetty/webapps/zimbra/m/mocompose ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moMessageAction.tag /opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moMessageAction.tag ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moBriefcaseToolbar.tag /opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moBriefcaseToolbar.tag ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moCalendarViewToolbar.tag /opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moCalendarViewToolbar.tag ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moTaskToolbar.tag /opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moTaskToolbar.tag ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moDisplayContact.tag /opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moDisplayContact.tag ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/mobile/moContactField.tag /opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/mobile/moContactField.tag ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Contacts_all.js.zgz /opt/zimbra/jetty/webapps/zimbra/js/Contacts_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/NewWindow2_all.js.zgz /opt/zimbra/jetty/webapps/zimbra/js/NewWindow2_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/MailCore_all.js.zgz /opt/zimbra/jetty/webapps/zimbra/js/MailCore_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Preferences_all.js.zgz /opt/zimbra/jetty/webapps/zimbra/js/Preferences_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup1_2_all.js.zgz /opt/zimbra/jetty/webapps/zimbra/js/Startup1_2_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Share_all.js.zgz /opt/zimbra/jetty/webapps/zimbra/js/Share_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Startup2_all.js.zgz /opt/zimbra/jetty/webapps/zimbra/js/Startup2_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/js/Extras_all.js.zgz /opt/zimbra/jetty/webapps/zimbra/js/Extras_all.js.zgz ZimbraBuild/storebuild/opt/zimbra/jetty-6.1.22.z6/webapps/zimbra/WEB-INF/tags/ruby.tag /opt/zimbra/jetty/webapps/zimbra/WEB-INF/tags/ruby.tag ================================================ FILE: rpmconf/Patch/installPatch.sh ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # ID=$(id -un) if [ x"$ID" != "xroot" ]; then echo "$0 must be run as root." exit 1 fi if [ $# -gt 1 ] then echo "usage: $0 [--force]" exit 1 fi if [ "x$1" != "x--force" -a "x$1" != "x" ] then echo "usage: $0 [--force]" exit 1 fi /usr/bin/perl bin/zmpatch.pl --config conf/zmpatch.xml --verbose $1 ================================================ FILE: rpmconf/Patch/libexec/zmcurl807-updater.sh ================================================ #!/bin/bash if [ x`whoami` != xroot ]; then echo Error: must be run as root user exit 1 fi VERSION=`su - zimbra -c 'zmcontrol -v'` VERSION=$(echo ${VERSION} | cut -d' ' -f2) VERSION=$(echo ${VERSION} | sed "s/_.*//") MAJOR=$(echo ${VERSION} | cut -d'.' -f1) MINOR=$(echo ${VERSION} | cut -d'.' -f2) PATCH=$(echo ${VERSION} | cut -d'.' -f3) if [ $MAJOR -ne 8 ]; then echo "Unsupported MAJOR version $MAJOR" exit 1 fi if [ $MINOR -ne 0 ]; then echo "Unsupported MINOR version $MINOR" exit 1 fi if [ $PATCH -lt 7 ]; then echo "Must be running 8.0.7" exit 1 fi if [ $PATCH -gt 7 ]; then echo "Must be running 8.0.7" exit 1 fi CURL_VERSION=7.35.0 if [ ! -d "/opt/zimbra/curl-${CURL_VERSION}" ]; then echo "Error: Unable to patch this release" exit 1 fi EGREP=`which egrep` if [ x$EGREP = "x" ]; then echo "Error: egrep not in path" exit 1 fi $EGREP 7.36.0 /opt/zimbra/curl-${CURL_VERSION}/bin/curl >/dev/null RC=$? if [ $RC -eq 0 ]; then echo "Error: Already patched" exit 1 fi ONLINE=1 if [ x"$1" = "x-o" -o x"$1" = "x--offline" ]; then ONLINE=0 fi cd /tmp PLAT=`/bin/sh /opt/zimbra/libexec/get_plat_tag.sh` if [ $ONLINE -eq 1 ]; then if [ -d curl/$PLAT ]; then rm -rf curl/$PLAT fi fi mkdir -p curl/$PLAT cd curl/$PLAT if [ $ONLINE -eq 1 ]; then WGET=`which wget` if [ x"$WGET" = "x" ]; then echo "Error: wget not in path" exit 1 fi fi MD5SUM=`which md5sum` if [ x"$MD5SUM" = "x" ]; then echo "Error: md5sum not in path" exit 1 fi if [ $ONLINE -eq 1 ]; then echo "Downloading patched curl" wget http://files.zimbra.com/downloads/8.0.${PATCH}_GA/curl/$PLAT/curl-${CURL_VERSION}.tgz >/dev/null 2>&1 RC=$? if [ $RC -ne 0 ]; then echo "Error: Unable to download curl" exit 1 fi wget http://files.zimbra.com/downloads/8.0.${PATCH}_GA/curl/$PLAT/curl-${CURL_VERSION}.tgz.md5sum >/dev/null 2>&1 RC=$? if [ $RC -ne 0 ]; then echo "Error: Unable to download md5sum" exit 1 fi fi echo -n "Validating patched curl: " DOWNLOAD_SUM=`$MD5SUM curl-${CURL_VERSION}.tgz` GOOD_SUM=`cat curl-${CURL_VERSION}.tgz.md5sum` if [ "$GOOD_SUM" = "$DOWNLOAD_SUM" ]; then echo "success" else echo "ERROR: MD5SUM mismatch" echo "Expected $GOOD_SUM" echo "Got $DOWNLOAD_SUM" exit 1 fi echo -n "Backing up old curl: " cd /opt/zimbra mv curl-${CURL_VERSION} curl-${CURL_VERSION}.sslprotocol.$$ echo "complete" echo -n "Installing patched curl: " tar xfz /tmp/curl/$PLAT/curl-${CURL_VERSION}.tgz echo "complete" echo "Curl patch process complete." echo "Please restart Zimbra Collaboration Suite as the Zimbra user via zmcontrol restart" ================================================ FILE: rpmconf/Patch/libexec/zmopenssl-updater.sh ================================================ #!/bin/bash if [ x`whoami` != xroot ]; then echo Error: must be run as root user exit 1 fi SSL[0]='1.0.1d' SSL[1]='1.0.1e' SSL[2]='1.0.1e' SSL[3]='1.0.1e' SSL[4]='1.0.1f' VERSION=`su - zimbra -c 'zmcontrol -v'` if [[ $VERSION == *ZCA* ]]; then VERSION=$(echo $VERSION|tr -d '\n') VERSION=$(expr "$VERSION" : '.*\(ZCS Build.*\)') VERSION=$(echo ${VERSION} | cut -d' ' -f3) else VERSION=$(echo ${VERSION} | cut -d' ' -f2) VERSION=$(echo ${VERSION} | sed "s/_.*//") fi MAJOR=$(echo ${VERSION} | cut -d'.' -f1) MINOR=$(echo ${VERSION} | cut -d'.' -f2) PATCH=$(echo ${VERSION} | cut -d'.' -f3) if [ $MAJOR -ne 8 ]; then echo "Unsupported MAJOR version $MAJOR" exit 1 fi if [ $MINOR -ne 0 ]; then echo "Unsupported MINOR version $MINOR" exit 1 fi if [ $PATCH -lt 3 ]; then echo "Must be running 8.0.3 or later" exit 1 fi if [ $PATCH -gt 7 ]; then echo "Must be running 8.0.7 or earlier" exit 1 fi ARPATCH=$(expr $PATCH - 3) SSL_VERSION=${SSL[$ARPATCH]} if [ ! -d "/opt/zimbra/openssl-${SSL_VERSION}" ]; then echo "Error: Unable to patch this release" exit 1 fi EGREP=`which egrep` if [ x$EGREP = "x" ]; then echo "Error: egrep not in path" exit 1 fi $EGREP dtls1_process_heartbeat /opt/zimbra/openssl-${SSL_VERSION}/lib/libssl.so.1.0.0 >/dev/null RC=$? if [ $RC -eq 1 ]; then echo "Error: Already patched" exit 1 fi ONLINE=1 if [ x"$1" = "x-o" -o x"$1" = "x--offline" ]; then ONLINE=0 fi cd /tmp PLAT=`/bin/sh /opt/zimbra/libexec/get_plat_tag.sh` if [ $ONLINE -eq 1 ]; then if [ -d openssl/$PLAT ]; then rm -rf openssl/$PLAT fi fi mkdir -p openssl/$PLAT cd openssl/$PLAT if [ $ONLINE -eq 1 ]; then WGET=`which wget` if [ x"$WGET" = "x" ]; then echo "Error: wget not in path" exit 1 fi fi MD5SUM=`which md5sum` if [ x"$MD5SUM" = "x" ]; then echo "Error: md5sum not in path" exit 1 fi if [ $ONLINE -eq 1 ]; then echo "Downloading patched openssl" wget http://files.zimbra.com/downloads/8.0.${PATCH}_GA/openssl/$PLAT/openssl-${SSL_VERSION}.tgz >/dev/null 2>&1 RC=$? if [ $RC -ne 0 ]; then echo "Error: Unable to download openssl" exit 1 fi wget http://files.zimbra.com/downloads/8.0.${PATCH}_GA/openssl/$PLAT/openssl-${SSL_VERSION}.tgz.md5sum >/dev/null 2>&1 RC=$? if [ $RC -ne 0 ]; then echo "Error: Unable to download md5sum" exit 1 fi fi echo -n "Validating patched openssl: " DOWNLOAD_SUM=`$MD5SUM openssl-${SSL_VERSION}.tgz` GOOD_SUM=`cat openssl-${SSL_VERSION}.tgz.md5sum` if [ "$GOOD_SUM" = "$DOWNLOAD_SUM" ]; then echo "success" else echo "ERROR: MD5SUM mismatch" echo "Expected $GOOD_SUM" echo "Got $DOWNLOAD_SUM" exit 1 fi echo -n "Backing up old openssl: " cd /opt/zimbra mv openssl-${SSL_VERSION} openssl-${SSL_VERSION}.brokenheart.$$ echo "complete" echo -n "Installing patched openssl: " tar xfz /tmp/openssl/$PLAT/openssl-${SSL_VERSION}.tgz echo "complete" echo "OpenSSL patch process complete." echo "Please restart Zimbra Collaboration Suite as the Zimbra user via zmcontrol restart" ================================================ FILE: rpmconf/Spec/Scripts/zimbra-core.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # # Create group, user for zimbra and postfix. H=`hostname --fqdn` I=`hostname -i` #Symlinks rm -f /opt/zimbra/java PLAT=`/opt/zimbra/libexec/get_plat_tag.sh` BIT=`echo $PLAT | awk -F_ '{print $2}'` if [ -d "/opt/zimbra/logger/db" ]; then chown zimbra:zimbra /opt/zimbra/logger/db fi if [ -f "/opt/zimbra/conf/ca/ca.pem" ]; then ln -f -s ca.pem /opt/zimbra/conf/ca/`openssl x509 -hash -noout -in /opt/zimbra/conf/ca/ca.pem`.0 fi if [[ $PLAT == "DEBIAN"* || $PLAT == "UBUNTU"* ]]; then sed -i -e '/^::1 ip6-localhost ip6-loopback localhost$/!s/::1 ip6-localhost ip6-loopback/::1 ip6-localhost ip6-loopback localhost/' /etc/hosts sed -i -e 's/# session required pam_limits.so/session required pam_limits.so/' /etc/pam.d/su pamtmp=`mktemp -t zpamtmp.XXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } egrep -v -e '^session[[:space:]]+required[[:space:]]+pam_limits.so' /etc/pam.d/common-session >$pamtmp echo "session required pam_limits.so" >> $pamtmp mv -f $pamtmp /etc/pam.d/common-session chmod 640 /etc/pam.d/common-session limitstmp=`mktemp -t zlimtmp.XXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } egrep -v -e '^root.*nofile' /etc/security/limits.conf > $limitstmp echo "root soft nofile 524288" >> $limitstmp echo "root hard nofile 524288" >> $limitstmp mv -f $limitstmp /etc/security/limits.conf chmod 640 /etc/security/limits.conf chown -R root:root /opt/zimbra/common/lib/perl5/Zimbra fi if [ -d /etc/logrotate.d ]; then cp -f /opt/zimbra/conf/zmlogrotate /etc/logrotate.d/zimbra fi cp -f /opt/zimbra/libexec/zimbra /etc/init.d/zimbra chmod 755 /etc/init.d/zimbra if [ -x /sbin/chkconfig ]; then chkconfig --del zimbra chkconfig --add zimbra chkconfig zimbra on elif [ -x /usr/sbin/update-rc.d ]; then update-rc.d -f zimbra remove update-rc.d zimbra start 99 2 5 . stop 01 0 1 6 . else rm -f /etc/rc*.d/S99zimbra rm -f /etc/rc*.d/S89zimbra rm -f /etc/rc*.d/K01zimbra if [ -d /etc/rc0.d ]; then ln -s /etc/init.d/zimbra /etc/rc0.d/S89zimbra ln -s /etc/init.d/zimbra /etc/rc0.d/K01zimbra fi if [ -d /etc/rc1.d ]; then ln -s /etc/init.d/zimbra /etc/rc1.d/K01zimbra fi if [ -d /etc/rc2.d ]; then ln -s /etc/init.d/zimbra /etc/rc2.d/S99zimbra ln -s /etc/init.d/zimbra /etc/rc2.d/K01zimbra fi if [ -d /etc/rc3.d ]; then ln -s /etc/init.d/zimbra /etc/rc3.d/S99zimbra ln -s /etc/init.d/zimbra /etc/rc3.d/K01zimbra fi if [ -d /etc/rc4.d ]; then ln -s /etc/init.d/zimbra /etc/rc4.d/S99zimbra ln -s /etc/init.d/zimbra /etc/rc4.d/K01zimbra fi if [ -d /etc/rc5.d ]; then ln -s /etc/init.d/zimbra /etc/rc5.d/S99zimbra ln -s /etc/init.d/zimbra /etc/rc5.d/K01zimbra fi if [ -d /etc/rc6.d ]; then ln -s /etc/init.d/zimbra /etc/rc6.d/S89zimbra ln -s /etc/init.d/zimbra /etc/rc6.d/K01zimbra fi fi mkdir -p /opt/zimbra/backup chown zimbra:zimbra /opt/zimbra/backup mkdir -p /opt/zimbra/log chown zimbra:zimbra /opt/zimbra/log mkdir -p /opt/zimbra/ssl chown zimbra:zimbra /opt/zimbra/ssl mkdir -p /opt/zimbra/.ssh chown zimbra:zimbra /opt/zimbra/.ssh mkdir -p /opt/zimbra/zmstat chown zimbra:zimbra /opt/zimbra/zmstat egrep -q '^%zimbra[[:space:]]' /etc/sudoers if [ $? = 0 ]; then sudotmp=`mktemp -t zsudoers.XXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } SUDOMODE=`perl -e 'my $mode=(stat("/etc/sudoers"))[2];if ($mode == "0000"){ $mode=33056 };printf("%04o\n",$mode & 07777);'`; egrep -v -e '^%zimbra[[:space:]]' /etc/sudoers > $sudotmp mv -f $sudotmp /etc/sudoers chmod $SUDOMODE /etc/sudoers fi chmod 440 /etc/sudoers.d/01_zimbra chown root:root /etc/sudoers.d/01_zimbra chmod 440 /etc/sudoers.d/02_zimbra-core chown root:root /etc/sudoers.d/02_zimbra-core if [ -x "/opt/zimbra/libexec/zmfixperms" ]; then /opt/zimbra/libexec/zmfixperms fi ================================================ FILE: rpmconf/Spec/Scripts/zimbra-core.pre ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # if [ "`echo /etc/security/limits.d/*-nproc.conf`" != "/etc/security/limits.d/*-nproc.conf" ]; then echo "zimbra soft nproc 278528" > /etc/security/limits.d/10-zimbra.conf echo "zimbra hard nproc 278528" >> /etc/security/limits.d/10-zimbra.conf echo "postfix soft nproc 278528" >> /etc/security/limits.d/10-zimbra.conf echo "postfix hard nproc 278528" >> /etc/security/limits.d/10-zimbra.conf echo "root soft nproc 278528" >> /etc/security/limits.d/10-zimbra.conf echo "root hard nproc 278528" >> /etc/security/limits.d/10-zimbra.conf fi if [ -f "/etc/security/limits.conf" ]; then limitstmp=`mktemp -t limitstmp.XXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } egrep -v -e '^zimbra.*nofile' /etc/security/limits.conf > $limitstmp echo "zimbra soft nofile 524288" >> $limitstmp echo "zimbra hard nofile 524288" >> $limitstmp mv -f $limitstmp /etc/security/limits.conf chmod 640 /etc/security/limits.conf else echo "zimbra soft nofile 524288" > /etc/security/limits.conf echo "zimbra hard nofile 524288" >> /etc/security/limits.conf chmod 640 /etc/security/limits.conf fi if [ -d "/opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store" ]; then if [ `ls -1 /opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/zm-ssdb-ephemeral-store-*.jar 2>/dev/null | wc -l` -gt 0 ]; then rm -rf /opt/zimbra/lib/ext/com_zimbra_ssdb_ephemeral_store/zm-ssdb-ephemeral-store-*.jar fi fi ================================================ FILE: rpmconf/Spec/Scripts/zimbra-dnscache.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # #Symlinks mkdir -p /opt/zimbra/data/dns/ca mkdir -p /opt/zimbra/data/dns/trust chown -R zimbra:zimbra /opt/zimbra/data/dns chown zimbra:zimbra /opt/zimbra/data egrep -q '^%zimbra[[:space:]]' /etc/sudoers if [ $? = 0 ]; then sudotmp=`mktemp -t zsudoers.XXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } SUDOMODE=`perl -e 'my $mode=(stat("/etc/sudoers"))[2];printf("%04o\n",$mode & 07777);'` egrep -v '^%zimbra[[:space:]]' /etc/sudoers > $sudotmp mv -f $sudotmp /etc/sudoers chmod $SUDOMODE /etc/sudoers fi chmod 440 /etc/sudoers.d/02_zimbra-dnscache chown root:root /etc/sudoers.d/02_zimbra-dnscache ================================================ FILE: rpmconf/Spec/Scripts/zimbra-ldap.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # # Create group, user for zimbra and postfix. shopt -s nullglob mkdir -p /opt/zimbra/data/ldap/state/run mkdir -p /opt/zimbra/data/ldap/config mkdir -p /opt/zimbra/data/ldap/mdb/db chown -R zimbra:zimbra /opt/zimbra/data/ldap chown -R root:root /opt/zimbra/common/etc/openldap if [ -x /opt/zimbra/common/libexec/slapd ]; then chown root:zimbra /opt/zimbra/common/libexec/slapd chmod 750 /opt/zimbra/common/libexec/slapd echo "Set capability for /opt/zimbra/common/libexec/slapd" setcap CAP_NET_BIND_SERVICE=+ep /opt/zimbra/common/libexec/slapd fi ================================================ FILE: rpmconf/Spec/Scripts/zimbra-logger.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # if [ -x "/opt/zimbra/libexec/zmfixperms" ]; then /opt/zimbra/libexec/zmfixperms fi ================================================ FILE: rpmconf/Spec/Scripts/zimbra-mta.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # #Symlinks PLAT=$(/opt/zimbra/libexec/get_plat_tag.sh) if [[ $PLAT == "UBUNTU"* || $PLAT == "DEBIAN"* ]]; then if [ ! -e "/usr/sbin/sendmail" -o -L "/usr/bin/sendmail" ]; then if [ -L "/usr/bin/sendmail" ]; then if [ -x /bin/readlink ]; then SMPATH=$(/bin/readlink /usr/sbin/sendmail) if [ x$SMPATH = x"/opt/zimbra/postfix/sbin/sendmail" -o x$SMPATH = x"/opt/zimbra/common/sbin/sendmail" ]; then /bin/rm -f /usr/sbin/sendmail ln -s /opt/zimbra/common/sbin/sendmail /usr/sbin/sendmail fi fi else ln -s /opt/zimbra/common/sbin/sendmail /usr/sbin/sendmail fi fi fi egrep -q '^%zimbra[[:space:]]' /etc/sudoers if [ $? = 0 ]; then sudotmp=`mktemp -t zsudoers.XXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } SUDOMODE=`perl -e 'my $mode=(stat("/etc/sudoers"))[2];printf("%04o\n",$mode & 07777);'` egrep -v '^%zimbra[[:space:]]' /etc/sudoers > $sudotmp mv -f $sudotmp /etc/sudoers chmod $SUDOMODE /etc/sudoers fi chmod 440 /etc/sudoers.d/02_zimbra-mta chown root:root /etc/sudoers.d/02_zimbra-mta chown zimbra:zimbra /opt/zimbra/common/conf/master.cf.in chmod 440 /opt/zimbra/common/conf/master.cf.in chown zimbra:zimbra /opt/zimbra/common/conf/tag_as_*.re.in mkdir -p /opt/zimbra/data/amavisd/db mkdir -p /opt/zimbra/data/amavisd/tmp mkdir -p /opt/zimbra/data/amavisd/var mkdir -p /opt/zimbra/data/amavisd/quarantine chown -R zimbra:zimbra /opt/zimbra/data/amavisd/* mkdir -p /opt/zimbra/data/opendkim chown -R zimbra:zimbra /opt/zimbra/data/opendkim mkdir -p /opt/zimbra/data/clamav/db chown -R zimbra:zimbra /opt/zimbra/data/clamav/db mkdir -p /opt/zimbra/data/postfix/spool/pid chown postfix:zimbra /opt/zimbra/data/postfix chown root:postfix /opt/zimbra/data/postfix/spool chown postfix:root /opt/zimbra/data/postfix/spool/pid chown zimbra:zimbra /opt/zimbra/data if [ ! -f /opt/zimbra/common/conf/main.cf ]; then touch /opt/zimbra/common/conf/main.cf chown zimbra:zimbra /opt/zimbra/common/conf/main.cf fi if [ ! -e /etc/aliases -o -L /etc/aliases ]; then if [ -L /etc/aliases ]; then if [ -x /bin/readlink ]; then SMPATH=$(/bin/readlink /etc/aliases) if [ x$SMPATH = x"/opt/zimbra/postfix/conf/aliases" -o x$SMPATH = x"/opt/zimbra/common/conf/aliases" ]; then rm -f /etc/aliases ln -s /opt/zimbra/common/conf/aliases /etc/aliases fi fi else ln -s /opt/zimbra/common/conf/aliases /etc/aliases fi fi if [ -x "/opt/zimbra/libexec/zmfixperms" ]; then /opt/zimbra/libexec/zmfixperms fi chgrp zimbra /opt/zimbra/common/conf chmod g+w /opt/zimbra/common/conf ================================================ FILE: rpmconf/Spec/Scripts/zimbra-proxy.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # chown -R zimbra:zimbra /opt/zimbra/conf/nginx if [ -f /opt/zimbra/log/nginx.log ]; then chown zimbra:zimbra /opt/zimbra/log/nginx.log chmod 644 /opt/zimbra/log/nginx.log fi if [ -f /opt/zimbra/log/nginx.access.log ]; then chown zimbra:zimbra /opt/zimbra/log/nginx.access.log chmod 644 /opt/zimbra/log/nginx.access.log fi if [ -x /opt/zimbra/common/sbin/nginx ]; then chown root:zimbra /opt/zimbra/common/sbin/nginx chmod 750 /opt/zimbra/common/sbin/nginx echo "Set capability for /opt/zimbra/common/sbin/nginx" setcap CAP_NET_BIND_SERVICE=+ep /opt/zimbra/common/sbin/nginx fi ================================================ FILE: rpmconf/Spec/Scripts/zimbra-qa.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # chown -R zimbra:zimbra /opt/zimbra/qa chmod a+x /opt/zimbra/qa/scripts/* ================================================ FILE: rpmconf/Spec/Scripts/zimbra-snmp.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # mkdir -p /opt/zimbra/data/snmp/persist mkdir -p /opt/zimbra/data/snmp/state chown -R zimbra:zimbra /opt/zimbra/data/snmp chown zimbra:zimbra /opt/zimbra/data chown root:root /opt/zimbra/common/share/snmp/mibs/zimbra*.mib chown root:root /opt/zimbra/common/share/snmp/snmp.conf chown root:root /opt/zimbra/common/conf/snmp.conf ================================================ FILE: rpmconf/Spec/Scripts/zimbra-spell.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # chown root:root /opt/zimbra/data/httpd/htdocs/aspell.php ================================================ FILE: rpmconf/Spec/Scripts/zimbra-store.post ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # H=`hostname -s` I=`hostname -i` if [ -f /opt/zimbra/db/db.sql ]; then mv /opt/zimbra/db/db.sql /opt/zimbra/db/db.sql.in sed -e "/server.hostname/ s/local/$H/" /opt/zimbra/db/db.sql.in > /opt/zimbra/db/db.sql chown zimbra:zimbra /opt/zimbra/db/db.sql* chmod 440 /opt/zimbra/db/db.sql* fi ( cd /opt/zimbra && rm -f jetty && ln -s jetty_base jetty ) ( cd /opt/zimbra && rm -f mailboxd && ln -s jetty_base mailboxd ) mkdir -p /opt/zimbra/mailboxd/logs chown zimbra:zimbra /opt/zimbra/mailboxd/logs mkdir -p /opt/zimbra/redolog mkdir -p /opt/zimbra/store mkdir -p /opt/zimbra/index mkdir -p /opt/zimbra/backup chown zimbra:zimbra /opt/zimbra/redolog /opt/zimbra/store /opt/zimbra/index /opt/zimbra/backup egrep -q '^%zimbra[[:space:]]' /etc/sudoers if [ $? = 0 ]; then sudotmp=`mktemp -t zsudoers.XXXXXX 2> /dev/null` || { echo "Failed to create tmpfile"; exit 1; } SUDOMODE=`perl -e 'my $mode=(stat("/etc/sudoers"))[2];printf("%04o\n",$mode & 07777);'` egrep -v -e '^%zimbra[[:space:]]' /etc/sudoers > $sudotmp mv -f $sudotmp /etc/sudoers chmod $SUDOMODE /etc/sudoers fi chmod 440 /etc/sudoers.d/02_zimbra-store chown root:root /etc/sudoers.d/02_zimbra-store if [ -d "/opt/zimbra/mailboxd/work/zimbra" ]; then find /opt/zimbra/mailboxd/work/zimbra -exec touch {} \; 2> /dev/null fi if [ -x "/opt/zimbra/libexec/zmfixperms" ]; then /opt/zimbra/libexec/zmfixperms fi ================================================ FILE: rpmconf/Spec/Scripts/zimbra-store.pre ================================================ #!/bin/bash # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # if [ -d "/opt/zimbra/mailboxd/work/zimbra" ]; then rm -rf /opt/zimbra/mailboxd/work/zimbra > /dev/null 2>&1 fi if [ -d "/opt/zimbra/mailboxd/work/zimbraAdmin" ]; then rm -rf /opt/zimbra/mailboxd/work/zimbraAdmin > /dev/null 2>&1 fi if [ -d "/opt/zimbra/lib/ext/smime" ]; then if [ `ls -1 /opt/zimbra/lib/ext/smime/zm-smime-*.jar 2>/dev/null | wc -l` -gt 0 ]; then rm -rf /opt/zimbra/lib/ext/smime/zm-smime-*.jar > /dev/null 2>&1 fi fi if [ -d "/opt/zimbra/extensions-extra/openidconsumer" ]; then if [ `ls -1 /opt/zimbra/extensions-extra/openidconsumer/zm-openid-consumer-store-*.jar 2>/dev/null | wc -l` -gt 0 ]; then rm -rf /opt/zimbra/extensions-extra/openidconsumer/zm-openid-consumer-store-*.jar > /dev/null 2>&1 fi fi ================================================ FILE: rpmconf/Spec/zimbra-apache.deb ================================================ Package: zimbra-apache Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core, zimbra-apache-components ================================================ FILE: rpmconf/Spec/zimbra-apache.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra Apache HTTPD server Name: zimbra-apache Version: @@VERSION@@ Release: @@RELEASE@@ License: Various Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no Requires: zimbra-core, zimbra-apache-components %description Best email money can buy %define __spec_install_pre /bin/true %define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil} %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-core.deb ================================================ Package: zimbra-core Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core-components@@MORE_DEPENDS@@ ================================================ FILE: rpmconf/Spec/zimbra-core.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra Core Name: zimbra-core Version: @@VERSION@@ Release: @@RELEASE@@ License: Various Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no Requires: zimbra-core-components@@MORE_DEPENDS@@ %description Best email money can buy %define __spec_install_pre /bin/true %define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil} %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-dnscache.deb ================================================ Package: zimbra-dnscache Version: @@VERSION@@ Description: Best email money can buy Maintainer: Zimbra Packaging Services Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core, zimbra-dnscache-components ================================================ FILE: rpmconf/Spec/zimbra-dnscache.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra DNS cache Name: zimbra-dnscache Version: @@VERSION@@ Release: @@RELEASE@@ License: ZPL and other Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no Requires: zimbra-core, zimbra-dnscache-components %description Best email money can buy %define __spec_install_pre /bin/true %define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil} %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-imapd.deb ================================================ Package: zimbra-imapd Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core ================================================ FILE: rpmconf/Spec/zimbra-imapd.spec ================================================ # # spec file for zimbra-imapd.rpm # Summary: Zimbra IMAP Name: zimbra-imapd Version: @@VERSION@@ Release: @@RELEASE@@ License: Various Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no requires: zimbra-core %description Best email money can buy %define __spec_install_pre /bin/true %if 0%{?rhel} == 9 %define __brp_ldconfig RPM_BUILD_ROOT="" /usr/lib/rpm/redhat/brp-ldconfig %define __brp_mangle_shebangs RPM_BUILD_ROOT="" /usr/lib/rpm/redhat/brp-mangle-shebangs %endif %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-ldap.deb ================================================ Package: zimbra-ldap Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core, zimbra-ldap-components ================================================ FILE: rpmconf/Spec/zimbra-ldap.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra LDAP Name: zimbra-ldap Version: @@VERSION@@ Release: @@RELEASE@@ License: OpenLDAP Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no Requires: zimbra-core, zimbra-ldap-components %description Best email money can buy %define __spec_install_pre /bin/true %define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil} %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-logger.deb ================================================ Package: zimbra-logger Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core ================================================ FILE: rpmconf/Spec/zimbra-logger.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra Mail Name: zimbra-logger Version: @@VERSION@@ Release: @@RELEASE@@ License: ZPL and other Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no requires: zimbra-core %description Best email money can buy %define __spec_install_pre /bin/true %define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil} %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-mta.deb ================================================ Package: zimbra-mta Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core, zimbra-mta-components Provides: mail-transport-agent Conflicts: mail-transport-agent Replaces: mail-transport-agent ================================================ FILE: rpmconf/Spec/zimbra-mta.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra MTA Name: zimbra-mta Version: @@VERSION@@ Release: @@RELEASE@@ License: Various Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no provides: @@MTA_PROVIDES@@ requires: zimbra-core, zimbra-mta-components %description Best email money can buy %define __spec_install_pre /bin/true %define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil} %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-proxy.deb ================================================ Package: zimbra-proxy Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core, zimbra-proxy-components, zimbra-memcached ================================================ FILE: rpmconf/Spec/zimbra-proxy.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra Proxy Name: zimbra-proxy Version: @@VERSION@@ Release: @@RELEASE@@ License: ZPL and other Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no requires: zimbra-core, zimbra-proxy-components, zimbra-memcached %description Best email money can buy %define __spec_install_pre /bin/true %define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil} %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-qa.deb ================================================ Package: zimbra-qa Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core ================================================ FILE: rpmconf/Spec/zimbra-qa.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra QA Tests Name: zimbra-qatest Version: @@VERSION@@ Release: @@RELEASE@@ License: ZPL Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no requires: zimbra-core %description Best email money can buy %define __spec_install_pre /bin/true %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-snmp.deb ================================================ Package: zimbra-snmp Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core, zimbra-snmp-components ================================================ FILE: rpmconf/Spec/zimbra-snmp.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra SNMP Name: zimbra-snmp Version: @@VERSION@@ Release: @@RELEASE@@ License: Various Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no requires: zimbra-core, zimbra-snmp-components %description Best email money can buy %define __spec_install_pre /bin/true %define __spec_install_post /usr/lib/rpm/brp-compress /usr/lib/rpm/brp-strip-comment-note %{nil} %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-spell.deb ================================================ Package: zimbra-spell Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core, zimbra-spell-components ================================================ FILE: rpmconf/Spec/zimbra-spell.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra Spell Name: zimbra-spell Version: @@VERSION@@ Release: @@RELEASE@@ License: Various Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no requires: zimbra-core, zimbra-spell-components %description Best email money can buy %define __spec_install_pre /bin/true %if 0%{?rhel} == 9 %define __brp_ldconfig RPM_BUILD_ROOT="" /usr/lib/rpm/redhat/brp-ldconfig %define __brp_mangle_shebangs RPM_BUILD_ROOT="" /usr/lib/rpm/redhat/brp-mangle-shebangs %endif %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Spec/zimbra-store.deb ================================================ Package: zimbra-store Version: @@VERSION@@ Description: Best email money can buy Maintainer: build@zimbra.com Section: Mail Priority: optional Architecture: @@ARCH@@ Depends: zimbra-core, zimbra-store-components, zimbra-jetty-distribution (>= 9.4.57.v20241219-2.@@PKG_OS_TAG@@)@@MORE_DEPENDS@@ ================================================ FILE: rpmconf/Spec/zimbra-store.spec ================================================ # # spec file for zimbra.rpm # Summary: Zimbra Mail Name: zimbra-store Version: @@VERSION@@ Release: @@RELEASE@@ License: ZPL and other Group: Applications/Messaging URL: http://www.zimbra.com Vendor: Zimbra, Inc. Packager: Zimbra, Inc. BuildRoot: /opt/zimbra AutoReqProv: no requires: zimbra-core, zimbra-store-components, zimbra-jetty-distribution >= 9.4.57.v20241219-2.@@PKG_OS_TAG@@@@MORE_DEPENDS@@ %description Best email money can buy %define __spec_install_pre /bin/true %if 0%{?rhel} == 9 %define __brp_ldconfig RPM_BUILD_ROOT="" /usr/lib/rpm/redhat/brp-ldconfig %define __brp_mangle_shebangs RPM_BUILD_ROOT="" /usr/lib/rpm/redhat/brp-mangle-shebangs %endif %prep %build %install %pre %post %preun %postun %files ================================================ FILE: rpmconf/Upgrade/zmupgrade.pm ================================================ #!/usr/bin/perl # vim: ts=2 # # ***** BEGIN LICENSE BLOCK ***** # Zimbra Collaboration Suite Server # Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2021 Synacor, Inc. # # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software Foundation, # version 2 of the License. # # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with this program. # If not, see . # ***** END LICENSE BLOCK ***** # package zmupgrade; use strict; use lib "/opt/zimbra/libexec/scripts"; use lib "/opt/zimbra/common/lib/perl5"; use Migrate; use Net::LDAP; use IPC::Open3; use FileHandle; use File::Grep qw (fgrep); use File::Path; use XML::Simple; my $zmlocalconfig="/opt/zimbra/bin/zmlocalconfig"; my $type = qx(${zmlocalconfig} -m nokey convertd_stub_name 2> /dev/null); chomp $type; if ($type eq "") {$type = "FOSS";} else {$type = "NETWORK";} my $rundir = qx(dirname $0); chomp $rundir; my $scriptDir = "/opt/zimbra/libexec/scripts"; my $lowVersion = 52; # Ensure to update the corresponding value in the zm-db-conf repository, # specifically in the file src/db/migration/zmdbupgrade.pl. my $hiVersion = 118; # this should be set to the DB version expected by current server code my $needSlapIndexing = 0; my $mysqlcnfUpdated = 0; my $platform = qx(/opt/zimbra/libexec/get_plat_tag.sh); chomp $platform; my $addr_space = (($platform =~ m/\w+_(\d+)/) ? "$1" : "32"); my $su = "su - zimbra -c"; my $hn = qx($su "${zmlocalconfig} -m nokey zimbra_server_hostname"); chomp $hn; my $isLdapMaster = qx($su "${zmlocalconfig} -m nokey ldap_is_master"); chomp($isLdapMaster); my $ZMPROV = "/opt/zimbra/bin/zmprov -r -m -l --"; my %updateScripts = ( '65' => "migrate20120611_7to8_bundle.pl", # this upgrades to 90 for 8_0_0_BETA # 66-79 skipped for possible HELIX use '80' => "migrate20110314-MobileDevices.pl", # 8.0.0_BETA1 '81' => "migrate20110330-RecipientsColumn.pl", # 8.0.0_BETA1 '82' => "migrate20110705-PendingAclPush.pl", # 8.0.0_BETA1 '83' => "migrate20110810-TagTable.pl", # 8.0.0_BETA1 '84' => "migrate20110928-MobileDevices.pl", # 8.0.0_BETA2 '85' => "migrate20110929-VersionColumn.pl", # 8.0.0_BETA2 '86' => "migrate20120125-uuidAndDigest.pl", # 8.0.0_BETA2 '87' => "migrate20120222-LastPurgeAtColumn.pl", # 8.0.0_BETA2 '88' => "migrate20120229-DropIMTables.pl", # 8.0.0_BETA2 '89' => "migrate20120319-Name255Chars.pl", '90' => "migrate20120410-BlobLocator.pl", '91' => "migrate20121009-VolumeBlobs.pl", # 8.0.1 '92' => "migrate20130226_alwayson.pl", # 8.5.0 # 93-99 skipped for possible IRONMAIDEN use '100' => "migrate20140319-MailItemPrevFolders.pl", # 8.5.0 '101' => "migrate20140328-EnforceTableCharset.pl", #8.5.0 '102' => "migrate20140624-DropMysqlIndexes.pl", #8.5.0 '103' => "migrate20150401-ZmgDevices.pl", #8.7.0 '104' => "migrate20150515-DataSourcePurgeTables.pl", #8.7.0 '105' => "migrate20150623-ZmgDevices.pl", #8.7.0 '106' => "migrate20150702-ZmgDevices.pl", #8.7.0 '107' => "migrate20170301-ZimbraChat.pl", #8.7.6 '108' => "migrate20180301-ZimbraChat.pl", #8.8.8 '109' => "migrate20190401-ZimbraChat.pl", #8.8.15 '110' => "migrate20190611-ZimbraChat.pl", #8.8.15 '111' => "migrate20210506-BriefcaseApi.pl", #10.0.0 '112' => "migrate20200625-MobileDevices.pl", #Zimbra X '113' => "migrate20210319-MobileDevices.pl", #Zimbra X '114' => "migrate20220721-AddMdmUpdateTimestamp.pl", #10.0.0 '115' => "migrate20220525-Volume.pl", #10.0.0 '116' => "migrate20220729-FilesShareWithMeFolder.pl", #10.0.0 '117' => "migrate20230224-UpdateOnlyOffice-7.2.1.pl", #10.0.0 ); my %updateFuncs = ( "7.0.0_GA" => \&upgrade700GA, "7.0.1_GA" => \&upgrade701GA, "7.1.0_GA" => \&upgrade710GA, "7.1.1_GA" => \&upgrade711GA, "7.1.3_GA" => \&upgrade713GA, "7.1.4_GA" => \&upgrade714GA, "7.2.0_GA" => \&upgrade720GA, "8.0.0_BETA1" => \&upgrade800BETA1, "8.0.0_BETA2" => \&upgrade800BETA2, "8.0.0_BETA3" => \&upgrade800BETA3, "8.0.0_BETA4" => \&upgrade800BETA4, "8.0.0_BETA5" => \&upgrade800BETA5, "8.0.0_GA" => \&upgrade800GA, "8.0.1_GA" => \&upgrade801GA, "8.0.2_GA" => \&upgrade802GA, "8.0.3_GA" => \&upgrade803GA, "8.0.4_GA" => \&upgrade804GA, "8.0.5_GA" => \&upgrade805GA, "8.0.6_GA" => \&upgrade806GA, "8.0.8_GA" => \&upgrade808GA, "8.5.0_BETA1" => \&upgrade850BETA1, "8.5.0_BETA2" => \&upgrade850BETA2, "8.5.0_BETA3" => \&upgrade850BETA3, "8.5.0_GA" => \&upgrade850GA, "8.5.1_GA" => \&upgrade851GA, "8.6.0_BETA1" => \&upgrade860BETA1, "8.6.0_BETA2" => \&upgrade860BETA2, "8.6.0_GA" => \&upgrade860GA, "8.7.0_BETA1" => \&upgrade870BETA1, "8.7.0_BETA2" => \&upgrade870BETA2, "8.7.0_RC1" => \&upgrade870RC1, "8.7.2_GA" => \&upgrade872GA, "8.8.6_GA" => \&upgrade886GA, "8.8.11_GA" => \&upgrade8811GA, "8.8.12_GA" => \&upgrade8812GA, "8.8.15_GA" => \&upgrade8815GA, ); my %updateMysql = ( "8.0.0_BETA1" => \&doMysql55Upgrade, "8.5.0_BETA3" => \&doMysql56Upgrade, "8.7.0_BETA1" => \&doMariaDB101Upgrade, ); sub version_cmp($$) { my $left = shift; my $right = shift; $left =~ s/ALPHA/0./; $right =~ s/ALPHA/0./; $left =~ s/BETA/1./; $right =~ s/BETA/1./; $left =~ s/RC/2./; $right =~ s/RC/2./; $left =~ s/GA/3./; $right =~ s/GA/3./; my @left_a = split(/[._]/, $left, 5); my @right_a = split(/[._]/, $right, 5); for( my $i = 0; $i < 5; ++$i ) { $left_a[$i] ||= 0; $right_a[$i] ||= 0; return -1 if( $left_a[$i] < $right_a[$i] ); return 1 if( $left_a[$i] > $right_a[$i] ); } return 0; } my ($startVersion,$startMajor,$startMinor,$startMicro); my ($targetVersion,$targetMajor,$targetMinor,$targetMicro,$targetMicroMicro,$targetType); sub applicableVersions { my $versionHash = shift; my @versionOrder; foreach my $key ( grep { !(version_cmp($_, $startVersion) < 0) } sort { version_cmp($a, $b); } keys %$versionHash) { push(@versionOrder,$key); } return \@versionOrder; } my @packageList = ( "zimbra-core", "zimbra-ldap", "zimbra-store", "zimbra-mta", "zimbra-snmp", "zimbra-logger", "zimbra-apache", "zimbra-spell", ); my %installedPackages = (); ##################### sub upgrade { $startVersion = shift; $targetVersion = shift; $main::config{HOSTNAME}=$hn; if (lc($isLdapMaster) eq "true" ) { if(main::isInstalled("zimbra-ldap")) { $isLdapMaster = 1; } else { $isLdapMaster = 0; } } else { $isLdapMaster = 0; } my ($startBuild,$targetBuild); ($startVersion,$startBuild) = $startVersion =~ /(\d+\.\d+\.\d+_[^_]*)_(\d+)/; ($targetVersion,$targetBuild) = $targetVersion =~ m/(\d+\.\d+\.\d+_[^_]*)_(\d+)/; ($startMajor,$startMinor,$startMicro) = $startVersion =~ /(\d+)\.(\d+)\.(\d+_[^_]*)/; ($targetMajor,$targetMinor,$targetMicro) = $targetVersion =~ /(\d+)\.(\d+)\.(\d+_[^_]*)/; ($targetMicroMicro, $targetType) = $targetMicro =~ /(\d+)_(.*)/; if ($startMajor < 7) { main::progress("ERROR: Upgrading from a ZCS version less than 7.0.0_GA is not supported\n"); return 1; } getInstalledPackages(); # Bug #73840 - need to delete /opt/zimbra/keyview before we try stopping services if ((! main::isInstalled("zimbra-convertd")) && (-l "/opt/zimbra/keyview")) { unlink("/opt/zimbra/keyview"); } if (stopZimbra()) { return 1; } if ($startVersion) { main::progress("This appears to be $startVersion\n"); } else { main::progress("ERROR: Unable to find initial version to upgrade from.\n"); main::progress(" This indicates a corrupted /opt/zimbra/.install_history file.\n"); main::progress(" DO NOT ATTEMPT UPGRADING AGAIN UNTIL THE FILE IS FIXED.\n"); return 1; } my $curSchemaVersion; if (main::isInstalled("zimbra-store") || main::isInstalled("zimbra-onlyoffice")) { if ($startMajor <= 7 || ($startMajor == 8 && $startMinor < 7)) { # Bug 96857 - MySQL meta files (pid file, socket, ..) should not be placed in db directory # temporary symlinks for relocation of key mysql files symlink("/opt/zimbra/db/mysql.pid", "/opt/zimbra/log/mysql.pid"); symlink("/opt/zimbra/db/mysql.sock", "/opt/zimbra/data/tmp/mysql/mysql.sock"); } foreach my $v (@{applicableVersions(\%updateMysql)}) { $updateMysql{$v}(); } if (startSql()) { return 1; }; $curSchemaVersion = Migrate::getSchemaVersion(); } main::setLocalConfig("ssl_allow_untrusted_certs", "true") if ($startMajor <= 7 && $targetMajor >= 8); # start ldap if (main::isInstalled ("zimbra-ldap")) { if($startMajor < 8) { my $rc=&upgradeLdap("8.0.0_BETA3"); if ($rc) { return 1; } } elsif(($startMajor == 8 && $startMinor < 5)) { my $rc=&upgradeLdap("8.5.0_BETA1"); if ($rc) { return 1; } } elsif (($startMajor == 8 && $startMinor <= 7)) { my $rc=&upgradeLdap("8.7.0_BETA2"); if ($rc) { return 1; } } if ($startMajor == 8 && $startMinor == 0 && $startMicro < 3) { my $rc=&reloadLdap("8.0.3_GA"); if ($rc) { return 1; } } if (startLdap()) {return 1;} } # Update our CA cert(s) for java/zmprov before we go further main::runAsZimbra("/opt/zimbra/bin/zmcertmgr createca"); main::runAsZimbra("/opt/zimbra/bin/zmcertmgr deployca -localonly"); if (main::isInstalled("zimbra-store") || main::isInstalled("zimbra-onlyoffice")) { doMysqlUpgrade(); doBackupRestoreVersionUpdate($startVersion); if ($curSchemaVersion < $hiVersion) { main::progress("Schema upgrade required from version $curSchemaVersion to $hiVersion.\n"); } # the old slow painful way (ie lots of mysql invocations) while ($curSchemaVersion >= $lowVersion && $curSchemaVersion < $hiVersion) { if (runSchemaUpgrade ($curSchemaVersion)) { return 1; } $curSchemaVersion = Migrate::getSchemaVersion(); } if ( $startMajor = 7 && $targetMajor >= 8) { # Bug #78297 my $imap_cache_data_files = "/opt/zimbra/data/mailboxd/imap-*"; system("/bin/rm -f ${imap_cache_data_files} 2> /dev/null"); } stopSql(); } if($startVersion ne $targetVersion # if you are upgrading across versions || $targetBuild > $startBuild) # or you are upgrading across new builds of the same version { main::configLDAPSchemaVersion() if ($isLdapMaster); foreach my $v (@{applicableVersions(\%updateFuncs)}) { main::progress("Applying updates for $v \n"); if (&{$updateFuncs{$v}}($startBuild, $targetVersion, $targetBuild)) { main::progress("Something failed while applying updates for $v - exiting\n"); return 1; } } } if ($isLdapMaster) { main::progress("Updating global config and COS's with attributes introduced after $startVersion..."); main::progress((&runAttributeUpgrade($startVersion)) ? "failed.\n" : "done.\n"); main::setLdapGlobalConfig("zimbraVersionCheckLastResponse", ""); } if ($needSlapIndexing) { main::detail("Updating slapd indices\n"); &indexLdap(); } if (main::isInstalled ("zimbra-ldap")) { stopLdap(); } return 0; } sub upgrade700GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-store")) { main::deleteLocalConfig("calendar_outlook_compatible_allday_events"); } return 0; } sub upgrade701GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-store")) { #56318 my $mysql_mycnf = main::getLocalConfig("mysql_mycnf"); if (!fgrep { /^max_allowed_packet/ } ${mysql_mycnf}) { main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-allowed-packet --section=mysqld --key=max_allowed_packet --set --value=16777216 ${mysql_mycnf}"); } if ( -d "/opt/zimbra/data/mailboxd/imap/cache" ) { system("/bin/rm -rf /opt/zimbra/data/mailboxd/imap/cache/* 2> /dev/null"); } } return 0; } sub upgrade710GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); my $mysql_data_directory = main::getLocalConfig("mysql_data_directory") || "/opt/zimbra/db/data"; my $zimbra_tmp_directory = main::getLocalConfig("zimbra_tmp_directory") || "/opt/zimbra/data/tmp"; my $mysql_mycnf = main::getLocalConfig("mysql_mycnf") || "/opt/zimbra/conf/my.cnf"; if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("53745"); runLdapAttributeUpgrade("55649"); runLdapAttributeUpgrade("57039"); runLdapAttributeUpgrade("57425"); } } if (main::isInstalled("zimbra-store")) { foreach my $i (qw(ib_logfile0 ib_logfile1)) { my $dbfile="${mysql_data_directory}/${i}"; main::detail("Moving $dbfile to ${zimbra_tmp_directory}/$i"); system("mv -f ${dbfile} ${zimbra_tmp_directory}/$i") if (-f ${dbfile}); } main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log_file_size --section=mysqld --key=innodb_log_file_size --set --value=524288000 ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-dirty-pages --section=mysqld --key=innodb_max_dirty_pages_pct --set --value=30 ${mysql_mycnf}"); } return 0; } sub upgrade711GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("57855"); runLdapAttributeUpgrade("58084"); runLdapAttributeUpgrade("58481"); runLdapAttributeUpgrade("58514"); runLdapAttributeUpgrade("59720"); } } if (main::isInstalled("zimbra-store")) { # 53272 if (-d "/opt/zimbra/jetty/webapps/spnego") { system("rm -rf /opt/zimbra/jetty/webapps/spnego"); } if (-d "/opt/zimbra/jetty/work/spnego") { system("rm -rf /opt/zimbra/jetty/work/spnego"); } } return 0; } sub upgrade713GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("11562"); runLdapAttributeUpgrade("63475"); } # 53301 - Fix ACLs for userCertificate for BES user and general usage my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); my $dn="olcDatabase={2}mdb,cn=config"; if ($isLdapMaster) { $result = $ldap->search( base=> "cn=accesslog", filter=>"(objectClass=*)", scope => "base", attrs => ['1.1'], ); my $size = $result->count; if ($size > 0 ) { $dn="olcDatabase={3}mdb,cn=config"; } } $result = $ldap->search( base=> "$dn", filter=>"(objectClass=*)", scope => "base", attrs => ['olcAccess'], ); my $entry=$result->entry($result->count-1); my @attrvals=$entry->get_value("olcAccess"); my $aclNumber=-1; my $attrMod=""; foreach my $attr (@attrvals) { if ($attr =~ /zimbraDomainName/) { ($aclNumber) = $attr =~ /^\{(\d+)\}*/; if ($attr !~ /uid=zmamavis,cn=appaccts,cn=zimbra/) { $attrMod=$attr; if ($attrMod =~ /by \* read/) { $attrMod =~ s/by \* read/by dn.base="uid=zmamavis,cn=appaccts,cn=zimbra" read by \* read/; } else { $attrMod =~ s/by \* none/by dn.base="uid=zmamavis,cn=appaccts,cn=zimbra" read by \* none/; } } } } if ($aclNumber != -1 && $attrMod ne "") { $result = $ldap->modify( $dn, delete => {olcAccess => "{$aclNumber}"}, ); $result = $ldap->modify( $dn, add =>{olcAccess=>"$attrMod"}, ); } $result = $ldap->search( base=> "$dn", filter=>"(objectClass=*)", scope => "base", attrs => ['olcAccess'], ); my $entry=$result->entry($result->count-1); my @attrvals=$entry->get_value("olcAccess"); my $aclNumber=-1; my $attrMod=""; my $fixup=0; foreach my $attr (@attrvals) { if ($attr =~ /homePhone,pager,mobile/) { if ($attr !~ /userCertificate/) { ($aclNumber) = $attr =~ /^\{(\d+)\}*/; $attrMod=$attr; } } if ($attr =~ /homePhone,mobile,pager/) { if ($attr !~ /userCertificate/) { ($aclNumber) = $attr =~ /^\{(\d+)\}*/; $attrMod=$attr; $fixup=1; } } } if ($aclNumber != -1 && $attrMod ne "") { if ($fixup) { $attrMod =~ s/homePhone,mobile,pager/homePhone,pager,mobile,userCertificate/; } else { $attrMod =~ s/homePhone,pager,mobile/homePhone,pager,mobile,userCertificate/; } $result = $ldap->modify( $dn, delete => {olcAccess => "{$aclNumber}"}, ); $result = $ldap->modify( $dn, add =>{olcAccess=>"$attrMod"}, ); } $ldap->unbind; } if (main::isInstalled("zimbra-mta")) { my $mtaNetworks=main::getLdapServerValue("zimbraMtaMyNetworks"); $mtaNetworks =~ s/,/ /g; if ($mtaNetworks =~ m/127\.0\.0\.0\/8/) { $mtaNetworks =~ s/ $//; $mtaNetworks=$mtaNetworks . " [::1]/128"; } main::setLdapServerConfig("zimbraMtaMyNetworks", "$mtaNetworks"); } return 0; } sub upgrade714GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { # 43040, must be done on all LDAP servers my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); my $ldap; chomp($ldap_pass); unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); unless($result->code()) { $result = $ldap->modify( "cn=config", add => { 'olcTLSCACertificatePath' => '/opt/zimbra/conf/ca'}); } $result = $ldap->unbind; } if (main::isInstalled("zimbra-mta")) { my @zimbraMtaRestriction = qx($su "$ZMPROV gacf zimbraMtaRestriction"); foreach my $restriction (@zimbraMtaRestriction) { $restriction =~ s/zimbraMtaRestriction: //; chomp $restriction; if ($restriction =~ /^reject_invalid_hostname$/) { main::runAsZimbra("$ZMPROV mcf -zimbraMtaRestriction reject_invalid_hostname"); main::runAsZimbra("$ZMPROV mcf +zimbraMtaRestriction reject_invalid_helo_hostname"); } if ($restriction =~ /^reject_non_fqdn_hostname$/) { main::runAsZimbra("$ZMPROV mcf -zimbraMtaRestriction reject_non_fqdn_hostname"); main::runAsZimbra("$ZMPROV mcf +zimbraMtaRestriction reject_non_fqdn_helo_hostname"); } if ($restriction =~ /^reject_unknown_client$/) { main::runAsZimbra("$ZMPROV mcf -zimbraMtaRestriction reject_unknown_client"); main::runAsZimbra("$ZMPROV mcf +zimbraMtaRestriction reject_unknown_client_hostname"); } if ($restriction =~ /^reject_unknown_hostname$/) { main::runAsZimbra("$ZMPROV mcf -zimbraMtaRestriction reject_unknown_hostname"); main::runAsZimbra("$ZMPROV mcf +zimbraMtaRestriction reject_unknown_helo_hostname"); } } } if (main::isInstalled("zimbra-store")) { main::setLocalConfig("calendar_cache_enabled", "true"); #66307 } return 0; } sub upgrade720GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); main::setLocalConfig("ldap_read_timeout", "0"); #70437 if (main::isInstalled("zimbra-store")) { # Bug #64466 my $imap_cache_data_directory = "/opt/zimbra/data/mailboxd/imap"; rmtree("${imap_cache_data_directory}") if ( -d "${imap_cache_data_directory}/"); if ( -d "/opt/zimbra/zimlets-deployed/com_zimbra_smime/") { main::runAsZimbra("/opt/zimbra/bin/zmzimletctl -l undeploy com_zimbra_smime"); system("rm -rf /opt/zimbra/mailboxd/webapps/service/zimlet/com_zimbra_smime") if (-d "/opt/zimbra/mailboxd/webapps/service/zimlet/com_zimbra_smime" ); } } return 0; } sub upgrade800BETA1 { my ($startBuild, $targetVersion, $targetBuild) = (@_); # bug 59607 - migrate old zmmtaconfig variables to zmconfigd foreach my $lc_var (qw(enable_config_restarts interval log_level listen_port debug watchdog watchdog_services)) { my $val = main::getLocalConfig("zmmtaconfig_${lc_var}"); if ($val ne "") { main::setLocalConfig("zmconfigd_${lc_var}", "$val"); main::deleteLocalConfig("zmmtaconfig_${lc_var}"); } } if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("57866"); runLdapAttributeUpgrade("57205"); runLdapAttributeUpgrade("57875"); } # 3884 main::progress("Adding dynamic group configuration\n"); main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20110615-AddDynlist.pl"); main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20110721-AddUnique.pl"); my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); my $dn="olcDatabase={2}mdb,cn=config"; if ($isLdapMaster) { $result = $ldap->search( base=> "cn=accesslog", filter=>"(objectClass=*)", scope => "base", attrs => ['1.1'], ); my $size = $result->count; if ($size > 0 ) { $dn="olcDatabase={3}mdb,cn=config"; } } $result = $ldap->search( base=> "$dn", filter=>"(objectClass=*)", scope => "base", attrs => ['olcDbIndex'], ); my $entry=$result->entry($result->count-1); my @attrvals=$entry->get_value("olcDbIndex"); my $MzimbraMemberOf=1; my $MzimbraSharedItem=1; foreach my $attr (@attrvals) { if ($attr =~ /zimbraMemberOf/) { $MzimbraMemberOf=0; } if ($attr =~ /zimbraSharedItem/) { $MzimbraSharedItem=0; } } if ($MzimbraMemberOf) { $result = $ldap->modify( $dn, add =>{olcDbIndex=>"zimbraMemberOf eq"}, ); } if ($MzimbraSharedItem) { $result = $ldap->modify( $dn, add =>{olcDbIndex=>"zimbraSharedItem eq,sub"}, ); } $ldap->unbind; if ($MzimbraMemberOf) { &indexLdapAttribute("zimbraMemberOf"); } if ($MzimbraSharedItem) { &indexLdapAttribute("zimbraSharedItem"); } } return 0; } sub upgrade800BETA2 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("63722"); runLdapAttributeUpgrade("64380"); runLdapAttributeUpgrade("65070"); runLdapAttributeUpgrade("66001"); runLdapAttributeUpgrade("60640"); } main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20111019-UniqueZimbraId.pl"); } if (main::isEnabled("zimbra-store")) { if (startSql()) { return 1; } main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20111005-ItemIdCheckpoint.pl"); # Bug: 60011 my $mysql_root_password=qx(/opt/zimbra/bin/zmlocalconfig -s -x -m nokey mysql_root_password); my $mysql_socket=qx(/opt/zimbra/bin/zmlocalconfig -s -x -m nokey mysql_socket); my $host=qx(hostname); chomp $mysql_root_password; chomp $mysql_socket; chomp $host; my $sql = < /dev/null") if (-d ${cache_dir}); } if (main::isInstalled("zimbra-proxy")) { main::runAsZimbra("$ZMPROV ms $hn -zimbraServiceInstalled imapproxy"); main::runAsZimbra("$ZMPROV ms $hn +zimbraServiceInstalled proxy"); if (main::isEnabled("zimbra-proxy")) { main::setLdapServerConfig($hn, '-zimbraServiceEnabled', 'imapproxy'); main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'proxy'); } } return 0; } sub upgrade800BETA3 { my ($startBuild, $targetVersion, $targetBuild) = (@_); main::setLocalConfig("ldap_read_timeout", "0"); #70437 main::detail("Removing /opt/zimbra/ssl/zimbra/{ca,server} to force creation or download of new ca and certificates."); system("rm -rf /opt/zimbra/ssl/zimbra/ca > /dev/null 2>&1"); system("rm -rf /opt/zimbra/ssl/zimbra/server > /dev/null 2>&1"); main::setLocalConfig("ssl_allow_untrusted_certs", "true"); if (main::isInstalled("zimbra-ldap")) { # Delete unused BDB DB keys foreach my $lc_var (qw(ldap_db_cachefree ldap_db_cachesize ldap_db_dncachesize ldap_db_idlcachesize ldap_db_shmkey ldap_overlay_syncprov_sessionlog)) { my $val = main::getLocalConfig("${lc_var}"); if ($val ne "") { main::deleteLocalConfig("${lc_var}"); } } foreach my $lc_var (qw(ldap_accesslog_cachefree ldap_accesslog_cachesize ldap_accesslog_dncachesize ldap_accesslog_idlcachesize ldap_accesslog_shmkey)) { my $val = main::getLocalConfig("${lc_var}"); if ($val ne "") { main::deleteLocalConfig("${lc_var}"); } } if ($isLdapMaster) { runLdapAttributeUpgrade("68831"); runLdapAttributeUpgrade("68891"); } main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20120210-AddSearchNoOp.pl"); } if (main::isInstalled("zimbra-store")) { if (-e "/opt/zimbra/jetty-6.1.22.z6/etc/jetty.keytab") { qx(mkdir -p /opt/zimbra/data/mailboxd/spnego); qx(cp -pf /opt/zimbra/jetty-6.1.22.z6/etc/jetty.keytab /opt/zimbra/data/mailboxd/spnego/jetty.keytab); } } if (main::isInstalled("zimbra-octopus")) { if (startSql()) { return 1; } main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20120209-octopusEvent.pl"); stopSql(); } return 0; } sub upgrade800BETA4 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("68190"); runLdapAttributeUpgrade("68394"); runLdapAttributeUpgrade("72007"); } my $doIndex = &addLdapIndex("zimbraDomainAliasTargetID","eq"); if ($doIndex) { &indexLdapAttribute("zimbraDomainAliasTargetID"); } $doIndex = &addLdapIndex("zimbraUCServiceId","eq"); if ($doIndex) { &indexLdapAttribute("zimbraUCServiceId"); } $doIndex = &addLdapIndex("DKIMIdentity", "eq"); if ($doIndex) { &indexLdapAttribute("DKIMIdentity"); } $doIndex = &addLdapIndex("DKIMSelector", "eq"); if ($doIndex) { &indexLdapAttribute("DKIMSelector"); } my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); my $dn="olcDatabase={2}mdb,cn=config"; if ($isLdapMaster) { $result = $ldap->search( base=> "cn=accesslog", filter=>"(objectClass=*)", scope => "base", attrs => ['1.1'], ); my $size = $result->count; if ($size > 0 ) { $dn="olcDatabase={3}mdb,cn=config"; } } $result = $ldap->search( base=> "$dn", filter=>"(objectClass=*)", scope => "base", attrs => ['olcAccess'], ); my $entry=$result->entry($result->count-1); my @attrvals=$entry->get_value("olcAccess"); my $aclNumber=-1; my $attrMod=""; foreach my $attr (@attrvals) { if ($attr =~ /zimbraAllowFromAddress/) { if ($attr !~ /DKIMIdentity/) { ($aclNumber) = $attr =~ /^\{(\d+)\}*/; $attrMod=$attr; } } } if ($aclNumber != -1 && $attrMod ne "") { $attrMod =~ s/zimbraAllowFromAddress/zimbraAllowFromAddress,DKIMIdentity,DKIMSelector,DKIMDomain,DKIMKey/; $result = $ldap->modify( $dn, delete => {olcAccess => "{$aclNumber}"}, ); $result = $ldap->modify( $dn, add =>{olcAccess=>"$attrMod"}, ); } $ldap->unbind; my $toolthreads = main::getLocalConfig("ldap_common_toolthreads"); if ($toolthreads == 1) { main::setLocalConfig("ldap_common_toolthreads", "2"); } main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20120507-UniqueDKIMSelector.pl"); } if (main::isInstalled("zimbra-proxy")) { # bug 32683 main::setLdapGlobalConfig("zimbraReverseProxySSLToUpstreamEnabled", "FALSE"); } foreach my $lc_var (qw(cbpolicyd_bind_host logger_mysql_bind_address logger_mysql_directory logger_mysql_data_directory logger_mysql_socket logger_mysql_pidfile logger_mysql_mycnf logger_mysql_errlogfile logger_mysql_port zimbra_logger_mysql_password)) { main::deleteLocalConfig("$lc_var"); } return 0; } sub upgrade800BETA5 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("67237"); } } return 0; } sub upgrade800GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("75450"); runLdapAttributeUpgrade("76427"); } } if (main::isInstalled("zimbra-mta")) { my $cbpdb="/opt/zimbra/data/cbpolicyd/db/cbpolicyd.sqlitedb"; if (-f $cbpdb) { main::runAsZimbra("sqlite3 $cbpdb < ${scriptDir}/migrate20130227-UpgradeCBPolicyDSchema.sql >/dev/null 2>&1"); main::runAsZimbra("sqlite3 $cbpdb < ${scriptDir}/migrate20130819-UpgradeQuotasTable.sql >/dev/null 2>&1"); } } return 0; } sub upgrade801GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); my $dn="olcDatabase={2}mdb,cn=config"; my $alog=0; if ($isLdapMaster) { $result = $ldap->search( base=> "cn=accesslog", filter=>"(objectClass=*)", scope => "base", attrs => ['1.1'], ); my $size = $result->count; if ($size > 0 ) { $dn="olcDatabase={3}mdb,cn=config"; $alog=1; } } $result = $ldap->search( base=> "$dn", filter=>"(objectClass=*)", scope => "base", attrs => ['olcDbEnvFlags'], ); my $entry=$result->entry($result->count-1); my @attrvals=$entry->get_value("olcDbEnvFlags"); if (!(@attrvals)) { $result = $ldap->modify( $dn, add =>{olcDbEnvFlags=>["writemap","nometasync"]}, ); } if ($isLdapMaster && $alog == 1) { $result = $ldap->search( base=> "olcDatabase={2}mdb,cn=config", filter=>"(objectClass=*)", scope => "base", attrs => ['olcDbEnvFlags'], ); my $entry=$result->entry($result->count-1); my @attrvals=$entry->get_value("olcDbEnvFlags"); if (!(@attrvals)) { $result = $ldap->modify( "olcDatabase={2}mdb,cn=config", add =>{olcDbEnvFlags=>["writemap","nometasync"]}, ); } } $ldap->unbind; } return 0; } sub upgrade802GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); $result = $ldap->modify( "uid=zmpostfix,cn=appaccts,cn=zimbra", replace => { zimbraId => "a8255e5f-142b-4aa0-8aab-f8591b6455ba", } ); $ldap->unbind; } } if (main::isInstalled("zimbra-mta")) { doAntiSpamMysql55Upgrade(); my $mtamilter = main::getLdapServerValue("zimbraMtaSmtpdMilters"); my $miltervalue="inet:localhost:8465"; if ($mtamilter ne "") { if ($mtamilter =~ /$miltervalue/) { $mtamilter =~ s/$miltervalue//; main::setLdapServerConfig("zimbraMtaSmtpdMilters", "$mtamilter"); } } } return 0; } sub upgrade803GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { main::setLocalConfig("ldap_common_toolthreads", "2"); } if (main::isInstalled("zimbra-store")) { my $mailboxd_java_options=main::getLocalConfigRaw("mailboxd_java_options"); if ($mailboxd_java_options =~ /-XX:MaxPermSize=128m/) { $mailboxd_java_options =~ s/-XX:MaxPermSize=128m/-XX:MaxPermSize=350m/; main::detail("Modified mailboxd_java_options=$mailboxd_java_options"); main::setLocalConfig("mailboxd_java_options", $mailboxd_java_options) } } main::deleteLocalConfig("zimbra_dos_filter_max_requests_per_sec"); return 0; } sub upgrade804GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); $result = $ldap->modify( "olcDatabase={2}mdb,cn=config", replace => { olcDbCheckpoint => "0 0", } ); if ($isLdapMaster) { $result = $ldap->modify( "olcDatabase={3}mdb,cn=config", replace => { olcDbCheckpoint => "0 0", } ); } $ldap->unbind; main::deleteLocalConfig("ldap_db_checkpoint"); main::deleteLocalConfig("ldap_accesslog_checkpoint"); if ($isLdapMaster) { runLdapAttributeUpgrade("75650"); } } if (main::isInstalled("zimbra-mta")) { main::setLdapServerConfig($hn, '+zimbraServiceInstalled', 'opendkim'); main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'opendkim'); $main::config{RUNDKIM}="yes"; main::deleteLocalConfig("cbpolicyd_timeout"); } if (main::isInstalled("zimbra-store")) { my $zimbraIPMode=main::getLdapServerValue("zimbraIPMode"); my $mysql_mycnf = main::getLocalConfig("mysql_mycnf"); if ($zimbraIPMode eq "ipv4") { main::setLocalConfig("mysql_bind_address", "127.0.0.1"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --unset ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --set --value=127.0.0.1 ${mysql_mycnf}"); } elsif ($zimbraIPMode eq "both") { main::setLocalConfig("mysql_bind_address", "::1"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --unset ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --set --value=::1 ${mysql_mycnf}"); } elsif ($zimbraIPMode eq "ipv6") { main::setLocalConfig("mysql_bind_address", "::1"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --unset ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-bind --section=mysqld --key=bind-address --set --value=::1 ${mysql_mycnf}"); } my $mailboxd_java_options=main::getLocalConfigRaw("mailboxd_java_options"); if ($mailboxd_java_options !~ /-Dorg.apache.jasper.compiler.disablejsr199/) { $mailboxd_java_options = $mailboxd_java_options." -Dorg.apache.jasper.compiler.disablejsr199=true"; main::detail("Modified mailboxd_java_options=$mailboxd_java_options"); main::setLocalConfig("mailboxd_java_options", $mailboxd_java_options) } } return 0; } sub upgrade805GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-mta")) { my $cbpdb="/opt/zimbra/data/cbpolicyd/db/cbpolicyd.sqlitedb"; if (-f $cbpdb) { main::runAsZimbra("sqlite3 $cbpdb < ${scriptDir}/migrate20130606-UpdateCBPolicydSchema.sql >/dev/null 2>&1"); } } if (main::isInstalled("zimbra-proxy")) { my $rpeioa=main::getLocalConfig("zimbra_reverseproxy_externalroute_include_original_authusername"); if(lc($rpeioa) eq "true") { main::setLdapGlobalConfig("zimbraReverseProxyExternalRouteIncludeOriginalAuthusername","TRUE"); } } main::deleteLocalConfig("zimbra_reverseproxy_externalroute_include_original_authusername"); return 0; } sub upgrade806GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isZCA()) { main::progress("ZCA Install detected. Removing VAMI Components..."); my $rc = main::runAsRoot("${scriptDir}/migrate20131014-removezca.pl"); main::progress(($rc == 0) ? "done.\n" : "failed. exiting.\n"); } my @zimbraStatThreadNamePrefix=qx($su "$ZMPROV gacf zimbraStatThreadNamePrefix"); if (! grep ( /qtp/, @zimbraStatThreadNamePrefix)) { main::runAsZimbra("$ZMPROV mcf +zimbraStatThreadNamePrefix qtp"); } return 0; } sub upgrade808GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); my $ldap_read_timeout=main::getLocalConfig("ldap_read_timeout"); if ($ldap_read_timeout == 0) { main::deleteLocalConfig("ldap_read_timeout"); #85299 } if (main::isInstalled("zimbra-ldap")) { my $ldap_common_writetimeout=main::getLocalConfig("ldap_common_writetimeout"); if ($ldap_common_writetimeout == 0) { main::deleteLocalConfig("ldap_common_writetimeout"); #85299 } } if (main::isInstalled("zimbra-mta")) { my @zimbraServiceInstalled=qx($su "$ZMPROV gs $hn zimbraServiceInstalled"); my @zimbraServiceEnabled=qx($su "$ZMPROV gs $hn zimbraServiceEnabled"); if (grep(/antivirus/, @zimbraServiceInstalled) || grep(/antispam/, @zimbraServiceInstalled) || grep(/archiving/, @zimbraServiceInstalled)) { main::setLdapServerConfig($hn, '+zimbraServiceInstalled', 'amavis'); } if (grep(/antivirus/, @zimbraServiceEnabled) || grep(/antispam/, @zimbraServiceEnabled) || grep(/archiving/, @zimbraServiceEnabled)) { main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'amavis'); } } return 0; } sub upgrade850BETA1 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-store")) { my $mailboxd_java_options=main::getLocalConfigRaw("mailboxd_java_options"); my $new_mailboxd_options=""; if ($mailboxd_java_options =~ /-XX:\+PrintGCTimeStamps/) { foreach my $option (split(/\s+/, $mailboxd_java_options)) { $new_mailboxd_options.=" $option" if ($option !~ /^-XX:\+PrintGCTimeStamps/); } $new_mailboxd_options .= " -XX:+PrintGCDateStamps" unless ($mailboxd_java_options =~ /PrintGCDateStamps/); $new_mailboxd_options =~ s/^\s+//; main::setLocalConfig("mailboxd_java_options", $new_mailboxd_options) if ($new_mailboxd_options ne ""); } if (main::isNetwork()) { my @zimbraReverseProxyUpstreamEwsServers=qx($su "$ZMPROV gacf zimbraReverseProxyUpstreamEwsServers"); if (! grep(/$hn/, @zimbraReverseProxyUpstreamEwsServers)) { main::runAsZimbra("$ZMPROV mcf +zimbraReverseProxyUpstreamEwsServers $hn"); } } main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'service'); main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'zimbra'); main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'zimbraAdmin'); main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'zimlet'); $main::config{SERVICEWEBAPP} = "yes"; $main::config{UIWEBAPPS} = "yes"; $main::installedWebapps{service} = "Enabled"; $main::installedWebapps{zimlet} = "Enabled"; $main::installedWebapps{zimbra} = "Enabled"; $main::installedWebapps{zimbraAdmin} = "Enabled"; } if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("81385"); } } if (main::isInstalled("zimbra-mta")) { my $antispam_mysql_mycnf = main::getLocalConfig("antispam_mysql_mycnf"); if ( -e ${antispam_mysql_mycnf} ) { main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-as-table_cache-fixup --section=mysqld --key=table_cache --unset ${antispam_mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-as-table_open_cache-fixup --section=mysqld --key=table_open_cache --setmin --value=1200 ${antispam_mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-innodb_data_file_path-fixup --section=mysqld --set --key=innodb_data_file_path --value=ibdata1:10M:autoextend ${antispam_mysql_mycnf}"); } my $disclaimerEnabled = main::getLdapConfigValue("zimbraDomainMandatoryMailSignatureEnabled"); if(lc($disclaimerEnabled) eq "true") { unlink("/opt/zimbra/data/altermime/global-default.txt"); unlink("/opt/zimbra/data/altermime/global-default.html"); my @domains = qx($su "$ZMPROV gad"); foreach my $domain (@domains) { chomp $domain; main::runAsZimbra("/opt/zimbra/libexec/zmaltermimeconfig -e $domain"); } } my $localxml = XMLin("/opt/zimbra/conf/localconfig.xml"); my $lc_attr= $localxml->{key}->{amavis_max_servers}->{value}; if (defined($lc_attr) && $lc_attr+0 != 0) { main::setLdapServerConfig($hn, 'zimbraAmavisMaxServers', "$lc_attr"); } $lc_attr= $localxml->{key}->{clamav_max_threads}->{value}; if (defined($lc_attr) && $lc_attr+0 != 0) { main::setLdapServerConfig($hn, 'zimbraClamAVMaxThreads', "$lc_attr"); } $lc_attr= $localxml->{key}->{amavis_enable_dkim_verification}->{value}; if (defined($lc_attr) && lc($lc_attr) eq "false") { main::setLdapServerConfig($hn, 'zimbraAmavisEnableDKIMVerification', "FALSE"); } $lc_attr= $localxml->{key}->{amavis_originating_bypass_sa}->{value}; if (defined($lc_attr) && lc($lc_attr) eq "true") { main::setLdapServerConfig($hn, 'zimbraAmavisOriginatingBypassSA', "TRUE"); } $lc_attr= $localxml->{key}->{amavis_dspam_enabled}->{value}; if (defined($lc_attr) && (lc($lc_attr) eq "yes" || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraAmavisDSPAMEnabled', "TRUE"); } $lc_attr= $localxml->{key}->{postfix_enable_smtpd_policyd}->{value}; if (defined($lc_attr) && (lc($lc_attr) eq "yes" || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraPostfixEnableSmtpdPolicyd', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_min_servers}->{value}; if (defined($lc_attr) && $lc_attr != 4) { main::setLdapServerConfig($hn, 'zimbraCBPolicydMinServers', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_min_spare_servers}->{value}; if (defined($lc_attr) && $lc_attr != 4) { main::setLdapServerConfig($hn, 'zimbraCBPolicydMinSpareServers', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_max_servers}->{value}; if (defined($lc_attr) && $lc_attr != 25) { main::setLdapServerConfig($hn, 'zimbraCBPolicydMaxServers', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_max_spare_servers}->{value}; if (defined($lc_attr) ne "" && $lc_attr != 12) { main::setLdapServerConfig($hn, 'zimbraCBPolicydMaxSpareServers', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_max_requests}->{value}; if (defined($lc_attr) && $lc_attr != 1000) { main::setLdapServerConfig($hn, 'zimbraCBPolicydMaxRequests', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_timeout_idle}->{value}; if (defined($lc_attr) && $lc_attr != 1020) { main::setLdapServerConfig($hn, 'zimbraCBPolicydTimeoutIdle', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_timeout_busy}->{value}; if (defined($lc_attr) && $lc_attr != 120) { main::setLdapServerConfig($hn, 'zimbraCBPolicydTimeoutBusy', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_bypass_timeout}->{value}; if (defined($lc_attr) && $lc_attr != 30) { main::setLdapServerConfig($hn, 'zimbraCBPolicydBypassTimeout', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_bypass_mode}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "tempfail" ) { main::setLdapServerConfig($hn, 'zimbraCBPolicydBypassMode', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_accesscontrol}->{value}; if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraCBPolicydAccessControlEnabled', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_greylisting}->{value}; if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraCBPolicydGreylistingEnabled', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_greylisting_training}->{value}; if ($lc_attr ne "" && (0+$lc_attr > 0 || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraCBPolicydGreylistingTrainingEnabled', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_greylisting_defer_msg}->{value}; if (defined($lc_attr)) { main::setLdapServerConfig($hn, 'zimbraCBPolicydGreylistingDeferMsg', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_greylisting_blacklist_msg}->{value}; if (defined($lc_attr)) { main::setLdapServerConfig($hn, 'zimbraCBPolicydGreylistingBlacklistMsg', "$lc_attr"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_checkhelo}->{value}; if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq "yes" || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraCBPolicydCheckHeloEnabled', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_checkspf}->{value}; if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq "yes" || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraCBPolicydCheckSPFEnabled', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_quotas}->{value}; if (defined($lc_attr) && (0+$lc_attr == 0 || lc($lc_attr) eq "no" || lc($lc_attr) eq "false")) { main::setLdapServerConfig($hn, 'zimbraCBPolicydQuotasEnabled', "FALSE"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_amavis}->{value}; if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq "yes" || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraCBPolicydAmavisEnabled', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_module_accounting}->{value}; if (defined($lc_attr) && (0+$lc_attr > 0 || lc($lc_attr) eq "yes" || lc($lc_attr) eq "true")) { main::setLdapServerConfig($hn, 'zimbraCBPolicydAccountingEnabled', "TRUE"); } $lc_attr= $localxml->{key}->{postfix_always_add_missing_headers}->{value}; if (defined($lc_attr) && lc($lc_attr) eq "no") { main::setLdapServerConfig($hn, 'zimbraMtaAlwaysAddMissingHeaders', "no"); } $lc_attr= $localxml->{key}->{postfix_broken_sasl_auth_clients}->{value}; if (defined($lc_attr) && lc($lc_attr) eq "no") { main::setLdapServerConfig($hn, 'zimbraMtaBrokenSaslAuthClients', "no"); } $lc_attr= $localxml->{key}->{postfix_bounce_notice_recipient}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "postmaster") { main::setLdapServerConfig($hn, 'zimbraMtaBounceNoticeRecipient', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_bounce_queue_lifetime}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "5d") { main::setLdapServerConfig($hn, 'zimbraMtaBounceQueueLifetime', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_delay_warning_time}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "0h") { main::setLdapServerConfig($hn, 'zimbraMtaDelayWarningTime', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_header_checks}->{value}; if (defined($lc_attr)) { if ($lc_attr =~ /\$\{zimbra_home\}/) { $lc_attr =~ s/\$\{zimbra_home\}/\/opt\/zimbra/; } $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaHeaderChecks', "$option"); } } $lc_attr= $localxml->{key}->{postfix_in_flow_delay}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "1s") { main::setLdapServerConfig($hn, 'zimbraMtaInFlowDelay', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_import_environment}->{value}; if (defined($lc_attr)) { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaImportEnvironment', "$option"); } } $lc_attr= $localxml->{key}->{postfix_lmtp_connection_cache_destinations}->{value}; if (defined($lc_attr)) { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaLmtpConnectionCacheDestinations', "$option"); } } $lc_attr= $localxml->{key}->{postfix_lmtp_connection_cache_time_limit}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "4s") { main::setLdapServerConfig($hn, 'zimbraMtaLmtpConnectionCacheTimeLimit', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_lmtp_host_lookup}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "dns") { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaLmtpHostLookup', "$option"); } } $lc_attr= $localxml->{key}->{postfix_queue_directory}->{value}; if (defined($lc_attr)) { if ($lc_attr =~ /\$\{zimbra_home\}/) { $lc_attr =~ s/\$\{zimbra_home\}/\/opt\/zimbra/; } main::setLdapServerConfig($hn, 'zimbraMtaQueueDirectory', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_maximal_backoff_time}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "4000s") { main::setLdapServerConfig($hn, 'zimbraMtaMaximalBackoffTime', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_minimal_backoff_time}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "300s") { main::setLdapServerConfig($hn, 'zimbraMtaMinimalBackoffTime', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_queue_run_delay}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "300s") { main::setLdapServerConfig($hn, 'zimbraMtaQueueRunDelay', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_milter_connect_timeout}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "30s") { main::setLdapServerConfig($hn, 'zimbraMtaMilterConnectTimeout', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_milter_content_timeout}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "300s") { main::setLdapServerConfig($hn, 'zimbraMtaMilterContentTimeout', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_milter_default_action}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "tempfail") { main::setLdapServerConfig($hn, 'zimbraMtaMilterDefaultAction', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtp_cname_overrides_servername}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "no") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpCnameOverridesServername', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtp_helo_name}->{value}; if (defined($lc_attr) && lc($lc_attr) ne '$myhostname') { main::setLdapServerConfig($hn, 'zimbraMtaSmtpHeloName', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtp_sasl_auth_enable}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "no") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpSaslAuthEnable', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtp_tls_security_level}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "may") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpTlsSecurityLevel', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtp_sasl_mechanism_filter}->{value}; if (defined($lc_attr)) { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaSmtpSaslMechanismFilter', "$option"); } } $lc_attr= $localxml->{key}->{postfix_smtp_sasl_password_maps}->{value}; if (defined($lc_attr)) { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; main::setLdapServerConfig($hn, 'zimbraMtaSmtpSaslPasswordMaps', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_policy_time_limit}->{value}; if (defined($lc_attr)) { main::setLdapServerConfig($hn, 'zimbraMtaPolicyTimeLimit', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_banner}->{value}; if (defined($lc_attr)) { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdBanner', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_proxy_timeout}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "100s") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdProxyTimeout', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_reject_unlisted_recipient}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "no") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdRejectUnlistedRecipient', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_reject_unlisted_sender}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "no") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdRejectUnlistedSender', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_sasl_authenticated_header}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "no") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdSaslAuthenticatedHeader', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_hard_error_limit}->{value}; if (defined($lc_attr) && $lc_attr != 20) { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdHardErrorLimit', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_soft_error_limit}->{value}; if (defined($lc_attr) && $lc_attr != 10) { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdSoftErrorLimit', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_error_sleep_time}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "1s") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdErrorSleepTime', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_helo_required}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "yes") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdHeloRequired', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_tls_loglevel}->{value}; if (defined($lc_attr) && $lc_attr != 1) { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdTlsLoglevel', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_virtual_alias_expansion_limit}->{value}; if (defined($lc_attr) && $lc_attr != 10000) { main::setLdapServerConfig($hn, 'zimbraMtaVirtualAliasExpansionLimit', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_virtual_transport}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "error") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdVirtualTransport', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_notify_classes}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "resource,software") { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaNotifyClasses', "$option"); } } $lc_attr= $localxml->{key}->{postfix_propagate_unmatched_extensions}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "canonical") { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaPropagateUnmatchedExtensions', "$option"); } } $lc_attr= $localxml->{key}->{postfix_sender_canonical_maps}->{value}; if (defined($lc_attr)) { if ($lc_attr =~ /\$\{zimbra_home\}/) { $lc_attr =~ s/\$\{zimbra_home\}/\/opt\/zimbra/g; } $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; main::setLdapServerConfig($hn, 'zimbraMtaSenderCanonicalMaps', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtp_sasl_security_options}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "noplaintext,noanonymous") { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaSmtpSaslSecurityOptions', "$option"); } } $lc_attr= $localxml->{key}->{postfix_smtpd_sasl_security_options}->{value}; if (defined($lc_attr) && lc($lc_attr) ne "noplaintext,noanonymous") { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaSmtpdSaslSecurityOptions', "$option"); } } $lc_attr= $localxml->{key}->{postfix_smtpd_sasl_tls_security_options}->{value}; if (defined($lc_attr)) { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaSmtpdSaslTlsSecurityOptions', "$option"); } } $lc_attr= $localxml->{key}->{postfix_smtpd_client_restrictions}->{value}; if (defined($lc_attr)) { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdClientRestrictions', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_smtpd_data_restrictions}->{value}; if (defined($lc_attr)) { main::setLdapServerConfig($hn, 'zimbraMtaSmtpdDataRestrictions', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_transport_maps}->{value}; if (defined($lc_attr)) { if ($lc_attr =~ /\$\{zimbra_home\}/) { $lc_attr =~ s/\$\{zimbra_home\}/\/opt\/zimbra/g; } $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; main::setLdapServerConfig($hn, 'zimbraMtaTransportMaps', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_virtual_alias_domains}->{value}; if (defined($lc_attr)) { if ($lc_attr =~ /\$\{zimbra_home\}/) { $lc_attr =~ s/\$\{zimbra_home\}/\/opt\/zimbra/g; } $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; main::setLdapServerConfig($hn, 'zimbraMtaVirtualAliasDomains', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_virtual_alias_maps}->{value}; if (defined($lc_attr)) { if ($lc_attr =~ /\$\{zimbra_home\}/) { $lc_attr =~ s/\$\{zimbra_home\}/\/opt\/zimbra/g; } $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; main::setLdapServerConfig($hn, 'zimbraMtaVirtualAliasMaps', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_virtual_mailbox_domains}->{value}; if (defined($lc_attr)) { if ($lc_attr =~ /\$\{zimbra_home\}/) { $lc_attr =~ s/\$\{zimbra_home\}/\/opt\/zimbra/g; } $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; main::setLdapServerConfig($hn, 'zimbraMtaVirtualMailboxDomains', "$lc_attr"); } $lc_attr= $localxml->{key}->{postfix_virtual_mailbox_maps}->{value}; if (defined($lc_attr)) { if ($lc_attr =~ /\$\{zimbra_home\}/) { $lc_attr =~ s/\$\{zimbra_home\}/\/opt\/zimbra/g; } $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; main::setLdapServerConfig($hn, 'zimbraMtaVirtualMailboxMaps', "$lc_attr"); } $lc_attr= $localxml->{key}->{sasl_smtpd_mech_list}->{value}; if (defined($lc_attr)) { $lc_attr =~ s/, /,/g; $lc_attr =~ s/\s+/ /g; foreach my $option (split(/,|\s/, $lc_attr)) { main::setLdapServerConfig($hn, '+zimbraMtaSaslSmtpdMechList', "$option"); } } $lc_attr= $localxml->{key}->{cbpolicyd_bind_port}->{value}; if (defined($lc_attr) && $lc_attr != 10031) { main::setLdapServerConfig($hn, 'zimbraCBPolicydBindPort', "TRUE"); } $lc_attr= $localxml->{key}->{cbpolicyd_log_level}->{value}; if (defined($lc_attr) && $lc_attr != 3) { main::setLdapServerConfig($hn, 'zimbraCBPolicydLogLevel', "TRUE"); } } main::deleteLocalConfig("amavis_max_servers"); main::deleteLocalConfig("clamav_max_threads"); main::deleteLocalConfig("amavis_enable_dkim_verification"); main::deleteLocalConfig("amavis_originating_bypass_sa"); main::deleteLocalConfig("amavis_dspam_enabled"); main::deleteLocalConfig("postfix_enable_smtpd_policyd"); main::deleteLocalConfig("cbpolicyd_min_servers"); main::deleteLocalConfig("cbpolicyd_min_spare_servers"); main::deleteLocalConfig("cbpolicyd_max_servers"); main::deleteLocalConfig("cbpolicyd_max_spare_servers"); main::deleteLocalConfig("cbpolicyd_max_requests"); main::deleteLocalConfig("cbpolicyd_timeout_idle"); main::deleteLocalConfig("cbpolicyd_timeout_busy"); main::deleteLocalConfig("cbpolicyd_bypass_timeout"); main::deleteLocalConfig("cbpolicyd_bypass_mode"); main::deleteLocalConfig("cbpolicyd_module_accesscontrol"); main::deleteLocalConfig("cbpolicyd_module_greylisting"); main::deleteLocalConfig("cbpolicyd_module_greylisting_training"); main::deleteLocalConfig("cbpolicyd_module_greylisting_defer_msg"); main::deleteLocalConfig("cbpolicyd_module_greylisting_blacklist_msg"); main::deleteLocalConfig("cbpolicyd_module_checkhelo"); main::deleteLocalConfig("cbpolicyd_module_checkspf"); main::deleteLocalConfig("cbpolicyd_module_quotas"); main::deleteLocalConfig("cbpolicyd_module_amavis"); main::deleteLocalConfig("cbpolicyd_module_accounting"); main::deleteLocalConfig("postfix_alias_maps"); main::deleteLocalConfig("postfix_always_add_missing_headers"); main::deleteLocalConfig("postfix_broken_sasl_auth_clients"); main::deleteLocalConfig("postfix_bounce_notice_recipient"); main::deleteLocalConfig("postfix_bounce_queue_lifetime"); main::deleteLocalConfig("postfix_command_directory"); main::deleteLocalConfig("postfix_daemon_directory"); main::deleteLocalConfig("postfix_delay_warning_time"); main::deleteLocalConfig("postfix_header_checks"); main::deleteLocalConfig("postfix_in_flow_delay"); main::deleteLocalConfig("postfix_import_environment"); main::deleteLocalConfig("postfix_lmtp_connection_cache_destinations"); main::deleteLocalConfig("postfix_lmtp_connection_cache_time_limit"); main::deleteLocalConfig("postfix_lmtp_host_lookup"); main::deleteLocalConfig("postfix_mailq_path"); main::deleteLocalConfig("postfix_manpage_directory"); main::deleteLocalConfig("postfix_newaliases_path"); main::deleteLocalConfig("postfix_queue_directory"); main::deleteLocalConfig("postfix_sendmail_path"); main::deleteLocalConfig("postfix_maximal_backoff_time"); main::deleteLocalConfig("postfix_minimal_backoff_time"); main::deleteLocalConfig("postfix_queue_run_delay"); main::deleteLocalConfig("postfix_milter_connect_timeout"); main::deleteLocalConfig("postfix_milter_command_timeout"); main::deleteLocalConfig("postfix_milter_content_timeout"); main::deleteLocalConfig("postfix_milter_default_action"); main::deleteLocalConfig("postfix_smtp_cname_overrides_servername"); main::deleteLocalConfig("postfix_smtp_helo_name"); main::deleteLocalConfig("postfix_smtp_sasl_auth_enable"); main::deleteLocalConfig("postfix_smtp_tls_security_level"); main::deleteLocalConfig("postfix_smtp_sasl_mechanism_filter"); main::deleteLocalConfig("postfix_smtp_sasl_password_maps"); main::deleteLocalConfig("postfix_policy_time_limit"); main::deleteLocalConfig("postfix_smtpd_banner"); main::deleteLocalConfig("postfix_smtpd_proxy_timeout"); main::deleteLocalConfig("postfix_smtpd_reject_unlisted_recipient"); main::deleteLocalConfig("postfix_smtpd_reject_unlisted_sender"); main::deleteLocalConfig("postfix_smtpd_sasl_authenticated_header"); main::deleteLocalConfig("postfix_smtpd_hard_error_limit"); main::deleteLocalConfig("postfix_smtpd_soft_error_limit"); main::deleteLocalConfig("postfix_smtpd_error_sleep_time"); main::deleteLocalConfig("postfix_smtpd_helo_required"); main::deleteLocalConfig("postfix_smtpd_tls_loglevel"); main::deleteLocalConfig("postfix_smtpd_tls_cert_file"); main::deleteLocalConfig("postfix_smtpd_tls_key_file"); main::deleteLocalConfig("postfix_virtual_alias_expansion_limit"); main::deleteLocalConfig("postfix_virtual_transport"); main::deleteLocalConfig("postfix_notify_classes"); main::deleteLocalConfig("postfix_propagate_unmatched_extensions"); main::deleteLocalConfig("postfix_sender_canonical_maps"); main::deleteLocalConfig("postfix_smtp_sasl_security_options"); main::deleteLocalConfig("postfix_smtpd_sasl_security_options"); main::deleteLocalConfig("postfix_smtpd_sasl_tls_security_options"); main::deleteLocalConfig("postfix_smtpd_client_restrictions"); main::deleteLocalConfig("postfix_smtpd_data_restrictions"); main::deleteLocalConfig("postfix_transport_maps"); main::deleteLocalConfig("postfix_virtual_alias_domains"); main::deleteLocalConfig("postfix_virtual_alias_maps"); main::deleteLocalConfig("postfix_virtual_mailbox_domains"); main::deleteLocalConfig("postfix_virtual_mailbox_maps"); main::deleteLocalConfig("sasl_smtpd_mech_list"); main::deleteLocalConfig("cbpolicyd_bind_port"); main::deleteLocalConfig("cbpolicyd_log_level"); return 0; } sub upgrade850BETA2 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { main::setLdapGlobalConfig("zimbraVersionCheckURL","https://www.zimbra.com/aus/universal/update.php"); } } if (main::isInstalled("zimbra-store")) { my $zimbra_log_directory = main::getLocalConfig("zimbra_log_directory"); my $mysql_mycnf = main::getLocalConfig("mysql_mycnf"); if ( -e ${mysql_mycnf} ) { main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-general_log_file-fixup --section=mysqld --set --key=general_log_file --value=${zimbra_log_directory}/mysql-mailboxd.log ${mysql_mycnf}"); } my $mailboxd_java_options=main::getLocalConfigRaw("mailboxd_java_options"); if ($mailboxd_java_options !~ /-Xloggc/) { $mailboxd_java_options .= " -Xloggc:/opt/zimbra/log/gc.log -XX:-UseGCLogFileRotation -XX:NumberOfGCLogFiles=20 -XX:GCLogFileSize=4096K"; $mailboxd_java_options =~ s/^\s+//; main::setLocalConfig("mailboxd_java_options", $mailboxd_java_options); } if (main::isStoreWebNode()) { my @zimbraReverseProxyUpstreamLoginServers=qx($su "$ZMPROV gacf zimbraReverseProxyUpstreamLoginServers"); if (! grep(/$hn/, @zimbraReverseProxyUpstreamLoginServers)) { main::runAsZimbra("$ZMPROV mcf +zimbraReverseProxyUpstreamLoginServers $hn"); } } } if (main::isInstalled("zimbra-mta")) { my $antispam_mysql_mycnf = main::getLocalConfig("antispam_mysql_mycnf"); my $zimbra_log_directory = main::getLocalConfig("zimbra_log_directory"); if ( -e ${antispam_mysql_mycnf} ) { main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-antispam-general_log_file-fixup --section=mysqld --set --key=general_log_file --value=${zimbra_log_directory}/mysql-antispam.log ${antispam_mysql_mycnf}"); } my @zimbraServiceInstalled=qx($su "$ZMPROV gs $hn zimbraServiceInstalled"); my @zimbraServiceEnabled=qx($su "$ZMPROV gs $hn zimbraServiceEnabled"); if (grep(/antivirus/, @zimbraServiceInstalled) || grep(/antispam/, @zimbraServiceInstalled) || grep(/archiving/, @zimbraServiceInstalled)) { main::setLdapServerConfig($hn, '+zimbraServiceInstalled', 'amavis'); } if (grep(/antivirus/, @zimbraServiceEnabled) || grep(/antispam/, @zimbraServiceEnabled) || grep(/archiving/, @zimbraServiceEnabled)) { main::setLdapServerConfig($hn, '+zimbraServiceEnabled', 'amavis'); } if (-f "/opt/zimbra/conf/sauser.cf") { qx(mv /opt/zimbra/conf/sauser.cf /opt/zimbra/data/spamassassin/localrules/sauser.cf); } if (-f "/opt/zimbra/conf/sa/sauser.cf") { qx(mv /opt/zimbra/conf/sa/sauser.cf /opt/zimbra/data/spamassassin/localrules/sauser.cf); } } return 0; } sub upgrade850BETA3 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { runLdapAttributeUpgrade("85224"); runLdapAttributeUpgrade("87674"); runLdapAttributeUpgrade("88766"); runLdapAttributeUpgrade("88098"); } } if (main::isInstalled("zimbra-store")) { if (main::isStoreServiceNode()) { my @zimbraReverseProxyAvailableLookupTargets=qx($su "$ZMPROV gacf zimbraReverseProxyAvailableLookupTargets"); if (! grep(/$hn/, @zimbraReverseProxyAvailableLookupTargets)) { main::runAsZimbra("$ZMPROV mcf +zimbraReverseProxyAvailableLookupTargets $hn"); } } } if (main::isInstalled("zimbra-mta")) { my $antispam_mysql_mycnf = main::getLocalConfig("antispam_mysql_mycnf"); if ( -e ${antispam_mysql_mycnf} ) { main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-long-query-time-fixup --section=mysqld --unset --key=long-query-time ${antispam_mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-long_query_time-fixup --section=mysqld --set --key=long_query_time --value=1 ${antispam_mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log-queries-not-using-indexes-fixup --section=mysqld --unset --key=log-queries-not-using-indexes ${antispam_mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log_queries_not_using_indexes-fixup --section=mysqld --set --key=log_queries_not_using_indexes ${antispam_mysql_mycnf}"); } } return 0; } sub upgrade850GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20140728-AddSSHA512.pl"); if ($isLdapMaster) { main::runAsZimbra("$ZMPROV mcf +zimbraSpamTrashAlias '/Deleted Messages'"); main::runAsZimbra("$ZMPROV mcf +zimbraSpamTrashAlias '/Deleted Items'"); } } return 0; } sub upgrade851GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } else { my $result = $ldap->bind("cn=config", password => $ldap_pass); $result = $ldap->search( base=> "cn=config,cn=zimbra", filter=>"(&(objectClass=*)(zimbraDomainMandatoryMailSignatureText=*))", scope => "base", attrs => ['zimbraDomainMandatoryMailSignatureText', 'zimbraDomainMandatoryMailSignatureHTML'], ); my $totalcount=$result->count; if ($totalcount > 0) { my $entry=$result->entry($totalcount-1); my $text_disclaimer = $entry->get_value("zimbraDomainMandatoryMailSignatureText"); my $html_disclaimer = $entry->get_value("zimbraDomainMandatoryMailSignatureHTML"); $result = $ldap->search( base=> "", filter=>"(objectClass=zimbraDomain)", scope => "sub", ); foreach $entry ($result->entries) { $result = $ldap->modify( $entry->dn, add =>{ zimbraAmavisDomainDisclaimerText=>$text_disclaimer, zimbraAmavisDomainDisclaimerHTML=>$html_disclaimer, }, ); } $result = $ldap->modify( "cn=config,cn=zimbra", delete=>['zimbraDomainMandatoryMailSignatureText','zimbraDomainMandatoryMailSignatureHTML'] ); } } } } return 0; } sub upgrade860BETA1 { my ($startBuild, $targetVersion, $targetBuild) = (@_); my $ssl_default_digest = main::getLocalConfig("ssl_default_digest"); if ($ssl_default_digest eq "sha1") { main::setLocalConfig("ssl_default_digest", "sha256"); } if (main::isInstalled("zimbra-snmp")) { my $val = main::getLocalConfig("snmp_trap_host"); if ($val =~ /\@/) { $val =~ s/.*\@//; main::setLocalConfig("snmp_trap_host", "$val"); } } return 0; } sub upgrade860BETA2 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20141022-AddTLSBits.pl"); } if (main::isInstalled("zimbra-store")) { my @zimbraHttpContextPathBasedThreadPoolBalancingFilterRules=qx($su "$ZMPROV gacf zimbraHttpContextPathBasedThreadPoolBalancingFilterRules"); foreach my $zimbraHttpContextPathBasedThreadPoolBalancingFilterRule (@zimbraHttpContextPathBasedThreadPoolBalancingFilterRules) { chomp($zimbraHttpContextPathBasedThreadPoolBalancingFilterRule); (my $filterKey, my $filterValue) = split(/:\s/, $zimbraHttpContextPathBasedThreadPoolBalancingFilterRule); if ($filterValue eq "/service:min=10;max=80%") { main::runAsZimbra("$ZMPROV mcf -zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '$filterValue'"); main::runAsZimbra("$ZMPROV mcf +zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '/service:max=80%'"); } elsif ($filterValue eq "/zimbra:min=10;max=15%") { main::runAsZimbra("$ZMPROV mcf -zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '$filterValue'"); main::runAsZimbra("$ZMPROV mcf +zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '/zimbra:max=15%'"); } elsif ($filterValue eq "/zimbraAdmin:min=10;max=5%") { main::runAsZimbra("$ZMPROV mcf -zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '$filterValue'"); main::runAsZimbra("$ZMPROV mcf +zimbraHttpContextPathBasedThreadPoolBalancingFilterRules '/zimbraAdmin:max=5%'"); } } } return 0; } sub upgrade860GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if(main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { my $mtasmtpdprotocols=main::getLdapConfigValue("zimbraMtaSmtpdTlsProtocols"); if ($mtasmtpdprotocols eq "") { main::runAsZimbra("$ZMPROV mcf zimbraMtaSmtpdTlsProtocols '!SSLv2, !SSLv3'"); } } } if ( -d "/opt/zimbra/zimlets-deployed/com_zimbra_linkedinimage/") { main::runAsZimbra("/opt/zimbra/bin/zmzimletctl -l undeploy com_zimbra_linkedinimage"); } return 0; } sub upgrade870BETA1 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if(main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { # Bug 99616 - Update olcSpSessionLog main::runAsZimbra("perl -I${scriptDir} ${scriptDir}/migrate20150930-AddSyncpovSessionlog.pl"); # Bug 96921 - Update Jetty default SSL cipher excludes... my $sslexcludeciph=main::getLdapConfigValue("zimbraSSLExcludeCipherSuites") || ""; my $cursslexcl=join(" ", sort split("\n", $sslexcludeciph)); my $oldsslexcl=join( " ", sort qw( SSL_RSA_WITH_DES_CBC_SHA SSL_DHE_RSA_WITH_DES_CBC_SHA SSL_DHE_DSS_WITH_DES_CBC_SHA SSL_RSA_EXPORT_WITH_RC4_40_MD5 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA ) ); if ($cursslexcl eq $oldsslexcl) { main::runAsZimbra("$ZMPROV mcf zimbraSSLExcludeCipherSuites '.*_RC4_.*'"); } # Bug 97332 - Some clients require SSLv2Hello support... my $sslprot=main::getLdapConfigValue("zimbraMailboxdSSLProtocols") || ""; my $cursslprot=join(" ", sort split("\n", $sslprot)); my $oldsslprot=join(" ", sort qw(TLSv1 TLSv1.1 TLSv1.2)); if ($cursslprot eq $oldsslprot) { main::runAsZimbra("$ZMPROV mcf +zimbraMailboxdSSLProtocols SSLv2Hello"); } } } if (main::isInstalled("zimbra-proxy")) { my $proxysslciphers=main::getLdapConfigValue("zimbraReverseProxySSLCiphers"); if ($proxysslciphers eq "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK") { main::runAsZimbra("$ZMPROV mcf zimbraReverseProxySSLCiphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4'"); } } if (main::isInstalled("zimbra-store")) { my $mailboxd_java_options=main::getLocalConfigRaw("mailboxd_java_options"); my $new_mailboxd_options = $mailboxd_java_options; $new_mailboxd_options =~ s/-XX:(?:Max|)PermSize=\S*\s?//g; if ($new_mailboxd_options ne $mailboxd_java_options) { main::progress("Updating mailboxd_java_options to remove deprecated PermSize and MaxPermSize java options.\n"); main::setLocalConfig("mailboxd_java_options", $new_mailboxd_options); } # Bug 80135 - Improved proxy timeout defaults... my $proxy_reconnect_timeout = main::getLdapServerValue("zimbraMailProxyReconnectTimeout"); if ($proxy_reconnect_timeout eq "60") { main::setLdapServerConfig($hn, 'zimbraMailProxyReconnectTimeout', '10'); } # Bug 96857 - MySQL meta files (pid file, socket, ..) should not be placed in db directory unlink("/opt/zimbra/db/mysql.pid") if (-e "/opt/zimbra/db/mysql.pid"); unlink("/opt/zimbra/db/mysql.sock") if (-e "/opt/zimbra/db/mysql.sock"); } my $localxml = XMLin("/opt/zimbra/conf/localconfig.xml"); my $lc_attr= $localxml->{key}->{zimbra_class_database}->{value}; if (defined($lc_attr) && $lc_attr eq "com.zimbra.cs.db.MySQL") { main::setLocalConfig("zimbra_class_database", "com.zimbra.cs.db.MariaDB"); } $lc_attr= $localxml->{key}->{short_term_all_effective_rights_cache_expiration}->{value}; if (defined($lc_attr) && $lc_attr+0 != 50000) { main::setLdapServerConfig($hn, 'zimbraShortTermAllEffectiveRightsCacheExpiration', "$lc_attr"."ms"); } $lc_attr= $localxml->{key}->{short_term_all_effective_rights_cache_size}->{value}; if (defined($lc_attr) && $lc_attr+0 != 128) { main::setLdapServerConfig($hn, 'zimbraShortTermAllEffectiveRightsCacheSize', "$lc_attr"); } $lc_attr= $localxml->{key}->{short_term_grantee_cache_expiration}->{value}; if (defined($lc_attr) && $lc_attr+0 != 50000) { main::setLdapServerConfig($hn, 'zimbraShortTermGranteeCacheExpiration', "$lc_attr"."ms"); } $lc_attr= $localxml->{key}->{short_term_grantee_cache_size}->{value}; if (defined($lc_attr) && $lc_attr+0 != 128) { main::setLdapServerConfig($hn, 'zimbraShortTermGranteeCacheSize', "$lc_attr"); } $lc_attr= $localxml->{key}->{zimbra_mailbox_throttle_reap_interval}->{value}; if (defined($lc_attr) && $lc_attr+0 != 60000) { main::setLdapServerConfig($hn, 'zimbraMailboxThrottleReapInterval', "$lc_attr"."ms"); } main::deleteLocalConfig("short_term_all_effective_rights_cache_expiration"); main::deleteLocalConfig("short_term_all_effective_rights_cache_size"); main::deleteLocalConfig("short_term_grantee_cache_expiration"); main::deleteLocalConfig("short_term_grantee_cache_size"); main::deleteLocalConfig("zimbra_mailbox_throttle_reap_interval"); return 0; } sub upgrade870BETA2 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-mta")) { my $antispam_mysql_mycnf = main::getLocalConfig("antispam_mysql_mycnf"); if ( -e ${antispam_mysql_mycnf} ) { main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_basedir --section=mysqld --key=basedir --set --value='/opt/zimbra/common' ${antispam_mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-error-log --section=mysqld_safe --key=err-log --unset ${antispam_mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-error-log --section=mysqld_safe --key=log-error --set --value=/opt/zimbra/log/mysqld.log ${antispam_mysql_mycnf}"); } main::setLdapServerConfig($hn, 'zimbraMtaCommandDirectory', "/opt/zimbra/common/sbin"); main::setLdapServerConfig($hn, 'zimbraMtaDaemonDirectory', "/opt/zimbra/common/libexec"); main::setLdapServerConfig($hn, 'zimbraMtaMailqPath', "/opt/zimbra/common/sbin/mailq"); main::setLdapServerConfig($hn, 'zimbraMtaManpageDirectory', "/opt/zimbra/common/share/man"); main::setLdapServerConfig($hn, 'zimbraMtaNewaliasesPath', "/opt/zimbra/common/sbin/newaliases"); main::setLdapServerConfig($hn, 'zimbraMtaSendmailPath', "/opt/zimbra/common/sbin/sendmail"); # Bug 98771 - Add support for DANE my $dns_setting = main::getLdapServerValue("zimbraMtaDnsLookupsEnabled"); if (lc($dns_setting) eq "false") { main::setLdapServerConfig($hn, 'zimbraMtaSmtpDnsSupportLevel', 'disabled'); } # Bug 98072 - We must clear zimbraMtaSenderCanonicalMaps on upgrade main::setLdapServerConfig($hn, 'zimbraMtaSenderCanonicalMaps', ""); main::setLdapGlobalConfig('zimbraMtaSenderCanonicalMaps',""); main::runAsZimbra("/opt/zimbra/bin/postconf -e sender_canonical_maps=''"); } if (main::isFoss()) { main::setLdapServerConfig($hn, '-zimbraServiceEnabled', 'vmware-ha'); } return 0; } sub upgrade870RC1 { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { if ($isLdapMaster) { main::setLdapGlobalConfig("zimbraSSLDHParam", "/opt/zimbra/conf/dhparam.pem.zcs"); } my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $@\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); my $dn="olcDatabase={2}mdb,cn=config"; if ($isLdapMaster) { $result = $ldap->search( base => "cn=accesslog", filter => "(objectClass=*)", scope => "base", attrs => ['1.1'], ); my $size = $result->count; if ($size > 0 ) { $dn="olcDatabase={3}mdb,cn=config"; } } $result = $ldap->search( base=> "$dn", filter=>"(objectClass=*)", scope => "base", attrs => ['olcDbRtxnSize'], ); my $entry = $result->entry($result->count-1); my @attrvals = $entry->get_value("olcDbRtxnSize"); if (!@attrvals) { $result = $ldap->modify( $dn, add => {olcDbRtxnSize=>0}, ); } $ldap->unbind; } return 0; } sub upgrade872GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); return 0; } sub upgrade886GA { my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-proxy")) { # In order to avoid breaking existing installations 'Strict Server Name Enforcement' capability # will remain disabled during upgrades. The maintainer may enable it after the upgrade process # has completed and after configuring the appropriate domain(s) with the relevant # 'zimbraVirtualHostName' and 'zimbraVirtualIPAddress' entries. This maintains current # behavior for all upgrades until the administrator decides to enable the strict name enforcement. main::setLdapServerConfig($hn, 'zimbraReverseProxyStrictServerNameEnabled', "FALSE"); } # ClientIpHash is now obsolete upgradeLdapConfigValue("zimbraImapLoadBalancingAlgorithm", "AccountIdHash", "ClientIpHash"); return 0; } sub upgrade8811GA { print "applying 8811GA upgrade changes"; my ($startBuild, $targetVersion, $targetBuild) = (@_); if (main::isInstalled("zimbra-ldap")) { my $doIndex = &addLdapIndex("zimbraOldMailAddress","eq"); if ($doIndex) { &indexLdapAttribute("zimbraOldMailAddress"); } my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); my $dn="olcDatabase={2}mdb,cn=config"; if ($isLdapMaster) { $result = $ldap->search( base=> "cn=accesslog", filter=>"(objectClass=*)", scope => "base", attrs => ['1.1'], ); my $size = $result->count; if ($size > 0 ) { $dn="olcDatabase={3}mdb,cn=config"; } } $result = $ldap->search( base=> "$dn", filter=>"(objectClass=*)", scope => "base", attrs => ['olcAccess'], ); my $entry=$result->entry($result->count-1); my @attrvals=$entry->get_value("olcAccess"); my $aclNumber=-1; my $attrMod=""; foreach my $attr (@attrvals) { if ($attr =~ /zimbraMailCatchAllAddress/) { if ($attr !~ /zimbraOldMailAddress/) { ($aclNumber) = $attr =~ /^\{(\d+)\}*/; $attrMod=$attr; } } } if ($aclNumber != -1 && $attrMod ne "") { $attrMod =~ s/zimbraMailCatchAllAddress/zimbraMailCatchAllAddress,zimbraOldMailAddress/; $result = $ldap->modify( $dn, delete => {olcAccess => "{$aclNumber}"}, ); $result = $ldap->modify( $dn, add =>{olcAccess=>"$attrMod"}, ); } $ldap->unbind; } return 0; } sub upgrade8812GA { print "applying 8812GA upgrade changes\n"; print "Updating to CA certs path\n"; qx($su "zmlocalconfig -e mailboxd_truststore=/opt/zimbra/common/lib/jvm/java/lib/security/cacerts"); qx($su "zmlocalconfig -e mailboxd_java_options='-server -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djdk.tls.client.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djava.awt.headless=true -Dsun.net.inetaddr.ttl=$ENV{networkaddress_cache_ttl} -Dorg.apache.jasper.compiler.disablejsr199=true -XX:+UseG1GC -XX:SoftRefLRUPolicyMSPerMB=1 -XX:-OmitStackTraceInFastThrow -verbose:gc -Xlog:gc*=debug,safepoint=info:file=/opt/zimbra/log/gc.log:time:filecount=20,filesize=10m -Djava.net.preferIPv4Stack=true'"); return 0; } sub upgrade8815GA { print "applying 8815GA upgrade changes\n"; print "Updating OWASP LC config\n"; main::deleteLocalConfig("zimbra_use_owasp_html_sanitizer"); return 0; } sub stopZimbra { main::progress("Stopping zimbra services..."); my $rc1 = main::runAsZimbra("/opt/zimbra/bin/zmcontrol stop"); main::progress(($rc1 == 0) ? "done.\n" : "failed. exiting.\n"); my $rc2 = 0; if (main::isInstalled("zimbra-license-daemon")) { main::progress("Stopping license daemon service..."); $rc2 = main::runAsZimbra("/opt/zimbra/bin/zmlicensectl --service stop"); main::progress(($rc2 == 0) ? "done.\n" : "failed. exiting.\n"); } my $exit_code = ($rc1 == 0 && $rc2 == 0) ? 0 : 1; return $exit_code; } sub startLdap { main::progress("Checking ldap status..."); my $rc = main::runAsZimbra("/opt/zimbra/bin/ldap status"); main::progress(($rc == 0) ? "already running.\n" : "not running.\n"); if ($rc) { main::progress("Checking ldap status..."); $rc = main::runAsZimbra("/opt/zimbra/bin/ldap status"); main::progress(($rc == 0) ? "already running.\n" : "not running.\n"); if ($rc) { main::progress("Starting ldap..."); my $rc = main::runAsZimbra("/opt/zimbra/bin/ldap start"); main::progress(($rc == 0) ? "done.\n" : "failed with exit code: $rc.\n"); if ($rc) { system("$su \"/opt/zimbra/bin/ldap start 2>&1 | grep failed\""); return $rc; } } } return 0; } sub stopLdap { main::progress("Stopping ldap..."); my $rc = main::runAsZimbra("/opt/zimbra/bin/ldap stop"); main::progress(($rc == 0) ? "done.\n" : "failed. ldap had exit status: $rc.\n"); sleep 5 unless $rc; # give it a chance to shutdown. return $rc; } sub isSqlRunning { my $rc = 0xffff & system("$su \"/opt/zimbra/bin/mysqladmin status > /dev/null 2>&1\""); $rc = $rc >> 8; return($rc ? undef : 1); } sub startSql { unless (isSqlRunning()) { main::progress("Starting mysql..."); my $rc = main::runAsZimbra("/opt/zimbra/bin/mysql.server start"); my $timeout = sleep 10; while (!isSqlRunning() && $timeout <= 1200 ) { $rc = main::runAsZimbra("/opt/zimbra/bin/mysql.server start"); $timeout += sleep 10; } main::progress(($rc == 0) ? "done.\n" : "failed.\n"); return $rc if $rc; } return(isSqlRunning() ? 0 : 1); } sub stopSql { if (isSqlRunning()) { main::progress("Stopping mysql..."); my $rc = main::runAsZimbra("/opt/zimbra/bin/mysql.server stop"); my $timeout = sleep 10; while (isSqlRunning() && $timeout <= 120 ) { $rc = main::runAsZimbra("/opt/zimbra/bin/mysql.server stop"); $timeout += sleep 10; } main::progress(($rc == 0) ? "done.\n" : "failed.\n"); return $rc if $rc; } return(isSqlRunning() ? 1 : 0); } sub isLoggerSqlRunning { my $rc = main::runAsZimbra("/opt/zimbra/bin/logmysqladmin status > /dev/null 2>&1"); return($rc ? undef : 1); } sub startLoggerSql { unless (isLoggerSqlRunning()) { main::progress("Starting logger mysql..."); my $rc = main::runAsZimbra("/opt/zimbra/bin/logmysql.server start"); my $timeout = sleep 10; while (!isLoggerSqlRunning() && $timeout <= 120 ) { $rc = main::runAsZimbra("/opt/zimbra/bin/logmysql.server start"); $timeout += sleep 10; } main::progress(($rc == 0) ? "done.\n" : "failed.\n"); return $rc if $rc; } return(isLoggerSqlRunning() ? 0 : 1); } sub stopLoggerSql { if (isLoggerSqlRunning()) { main::progress("Stopping logger mysql..."); my $rc = main::runAsZimbra("/opt/zimbra/bin/logmysql.server stop"); my $timeout = sleep 10; while (isLoggerSqlRunning() && $timeout <= 120 ) { $rc = main::runAsZimbra("/opt/zimbra/bin/logmysql.server stop"); $timeout += sleep 10; } main::progress(($rc == 0) ? "done.\n" : "failed.\n"); return $rc if $rc; } return(isLoggerSqlRunning() ? 1 : 0); } sub runSchemaUpgrade { my $curVersion = shift; if (! defined ($updateScripts{$curVersion})) { main::progress ("Can't upgrade from version $curVersion - no script!\n"); return 1; } if (! -x "${scriptDir}/$updateScripts{$curVersion}" ) { main::progress ("Can't run ${scriptDir}/$updateScripts{$curVersion} - not executable!\n"); return 1; } main::progress ("Running ${scriptDir}/$updateScripts{$curVersion}\n"); open(MIG, "$su \"/usr/bin/perl -I${scriptDir} ${scriptDir}/$updateScripts{$curVersion}\" 2>&1|"); while () { main::progress($_); } close(MIG); my $rc = $?; if ($rc != 0) { main::progress ("Script failed with code $rc: $! - exiting\n"); return $rc; } return 0; } sub getInstalledPackages { foreach my $p (@packageList) { if (main::isInstalled($p)) { $installedPackages{$p} = $p; } } } sub cleanPostfixLC { my ($var,$val); foreach $var (qw(command_directory daemon_directory mailq_path manpage_directory newaliases_path queue_directory sendmail_path)) { $val = main::getLocalConfig("postfix_${var}"); if ($val =~ /postfix-(\d.*)\//) { main::detail("Removing $1 from postfix_${var}"); $val =~ s/postfix-\d.*\//postfix\//; main::setLocalConfig("postfix_${var}", "$val"); } } } sub updateMySQLcnf { return if ($mysqlcnfUpdated == 1); my $mycnf = "/opt/zimbra/conf/my.cnf"; my $mysql_pidfile = main::getLocalConfig("mysql_pidfile"); $mysql_pidfile = "/opt/zimbra/db/mysql.pid" if ($mysql_pidfile eq ""); if (-e "$mycnf") { unless (open(MYCNF, "$mycnf")) { Migrate::myquit(1, "${mycnf}: $!\n"); } my @CNF = ; close(MYCNF); my $i=0; my $mycnfChanged = 0; my $tmpfile = "/tmp/my.cnf.$$";; my $zimbra_user = qx(${zmlocalconfig} -m nokey zimbra_user 2> /dev/null) || "zimbra";; my $zimbra_tmp_directory = qx(${zmlocalconfig} -m nokey zimbra_tmp_directory 2> /dev/null) || "/opt/zimbra/data/tmp"; open(TMP, ">$tmpfile"); foreach (@CNF) { if (/^port/ && $CNF[$i+1] !~ m/^user/) { print TMP; print TMP "user = $zimbra_user\n"; $mycnfChanged=1; next; } elsif (/^err-log/ && $CNF[$i+1] !~ m/^pid-file/) { print TMP; print TMP "pid-file = ${mysql_pidfile}\n"; $mycnfChanged=1; next; } elsif (/^thread_cache\s+=\s+(\d+)$/) { # 29475 fix thread_cache_size if ($1 > 110) { s/^thread_cache/thread_cache_size/g; print TMP; } else { print TMP "thread_cache_size = 110\n"; next; } $mycnfChanged=1; next; } elsif (/^thread_cache_size\s+=\s+(\d+)$/) { if ($1 < 110) { $mycnfChanged=1; print TMP "thread_cache_size = 110\n"; next; } } elsif (/^max_connections\s+=\s+(\d+)$/) { if ($1 < 110) { $mycnfChanged=1; print TMP "max_connections = 110\n"; next; } } elsif (/^skip-external-locking/) { # 19749 remove skip-external-locking print TMP "external-locking\n"; $mycnfChanged=1; next; } elsif (/^innodb_open_files/) { # 24906 print TMP; print TMP "innodb_max_dirty_pages_pct = 10\n" unless(grep(/^innodb_max_dirty_pages_pct/, @CNF)); print TMP "innodb_flush_method = O_DIRECT\n" unless(grep(/^innodb_flush_method/, @CNF)); $mycnfChanged=1; next; } elsif (/^user/ && $CNF[$i+1] !~ m/^tmpdir/) { print TMP; print TMP "tmpdir = $zimbra_tmp_directory\n"; $mycnfChanged=1; next; } print TMP; $i++; } close(TMP); if ($mycnfChanged) { qx(mv $mycnf ${mycnf}.${startVersion}); qx(cp -f $tmpfile $mycnf); qx(chmod 644 $mycnf); } } } sub clearTomcatWorkDir { my $workDir = "/opt/zimbra/tomcat/work"; return unless (-d "$workDir"); system("find $workDir -type f -exec rm -f {} \\\;"); } sub clearRedologDir($$) { my ($redologDir, $version) = @_; if (-d "$redologDir" && ! -e "${redologDir}/${version}") { qx(mkdir ${redologDir}/${version}); qx(mv ${redologDir}/* ${redologDir}/${version}/ > /dev/null 2>&1); qx(chown zimbra:zimbra $redologDir > /dev/null 2>&1); } return; } sub clearBackupDir($$) { my ($backupDir, $version) = @_; if (-e "$backupDir" && ! -e "${backupDir}/${version}") { qx(mkdir ${backupDir}/${version}); qx(mv ${backupDir}/* ${backupDir}/${version} > /dev/null 2>&1); qx(chown zimbra:zimbra $backupDir > /dev/null 2>&1); } return; } sub doMysql55Upgrade { my $mysql_mycnf = main::getLocalConfig("mysql_mycnf"); my $zimbra_log_directory = main::getLocalConfig("zimbra_log_directory") || "/opt/zimbra/log"; main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion} --section=mysqld --unset --key=ignore-builtin-innodb ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion} --section=mysqld --unset --key=plugin-load ${mysql_mycnf}"); } sub doAntiSpamMysql55Upgrade { my $antispam_mysql_mycnf = main::getLocalConfig("antispam_mysql_mycnf"); my $zimbra_log_directory = main::getLocalConfig("zimbra_log_directory") || "/opt/zimbra/log"; if ( -e ${antispam_mysql_mycnf} ) { main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion} --section=mysqld --unset --key=ignore-builtin-innodb ${antispam_mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion} --section=mysqld --unset --key=plugin-load ${antispam_mysql_mycnf}"); } } sub doMysql56Upgrade { my $mysql_mycnf = main::getLocalConfig("mysql_mycnf"); my $zimbra_log_directory = main::getLocalConfig("zimbra_log_directory") || "/opt/zimbra/log"; main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-table_cache-fixup --section=mysqld --key=table_cache --unset ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-table_open_cache-fixup --section=mysqld --key=table_open_cache --setmin --value=1200 ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-innodb_data_file_path-fixup --section=mysqld --set --key=innodb_data_file_path --value=ibdata1:10M:autoextend ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-long-query-time-fixup --section=mysqld --unset --key=long-query-time ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-long_query_time-fixup --section=mysqld --set --key=long_query_time --value=1 ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log-queries-not-using-indexes-fixup --section=mysqld --unset --key=log-queries-not-using-indexes ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-log_queries_not_using_indexes-fixup --section=mysqld --set --key=log_queries_not_using_indexes ${mysql_mycnf}"); } sub doMariaDB101Upgrade { my $mysql_mycnf = main::getLocalConfig("mysql_mycnf"); main::deleteLocalConfig("mysql_socket"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_socket --section=mysqld --key=socket --set --value='/opt/zimbra/data/tmp/mysql/mysql.sock' ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_pidfile --section=mysqld --key=pid-file --set --value='/opt/zimbra/log/mysql.pid' ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_pidfile --section=mysqld_safe --key=pid-file --set --value='/opt/zimbra/log/mysql.pid' ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-mysql_basedir --section=mysqld --key=basedir --set --value='/opt/zimbra/common' ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-error-log --section=mysqld_safe --key=err-log --unset ${mysql_mycnf}"); main::runAsZimbra("/opt/zimbra/libexec/zminiutil --backup=.pre-${targetVersion}-error-log --section=mysqld_safe --key=log-error --set --value=/opt/zimbra/log/mysqld.log ${mysql_mycnf}"); } sub doMysqlUpgrade { my $db_pass = main::getLocalConfig("mysql_root_password"); my $zimbra_tmp = main::getLocalConfig("zimbra_tmp_directory") || "/opt/zimbra/data/tmp"; my $mysql_socket = main::getLocalConfig("mysql_socket"); my $mysql_mycnf = main::getLocalConfig("mysql_mycnf"); my $mysqlUpgrade = "/opt/zimbra/common/bin/mysql_upgrade"; my $cmd = "$mysqlUpgrade --defaults-file=$mysql_mycnf -S $mysql_socket --user=root --password=$db_pass"; main::progress("Running mysql_upgrade..."); main::runAsZimbra("$cmd > ${zimbra_tmp}/mysql_upgrade.out 2>&1"); main::progress("done.\n"); } sub doBackupRestoreVersionUpdate($) { my ($startVersion) = @_; my ($prevRedologVersion,$currentRedologVersion,$prevBackupVersion,$currentBackupVersion); $prevRedologVersion = &Migrate::getRedologVersion; $currentRedologVersion = qx($su "zmjava com.zimbra.cs.redolog.util.GetVersion"); chomp($currentRedologVersion); return unless ($currentRedologVersion); Migrate::insertRedologVersion($currentRedologVersion) if ($prevRedologVersion eq ""); if ($prevRedologVersion != $currentRedologVersion) { main::progress("Redolog version update required.\n"); Migrate::updateRedologVersion($prevRedologVersion,$currentRedologVersion); main::progress("Redolog version update finished.\n"); } if (-f "/opt/zimbra/lib/ext/backup/zimbrabackup.jar") { $prevBackupVersion = &Migrate::getBackupVersion; $currentBackupVersion = qx($su "zmjava com.zimbra.cs.backup.util.GetVersion"); chomp($currentBackupVersion); return unless ($currentBackupVersion); Migrate::insertBackupVersion($currentBackupVersion) if ($prevBackupVersion eq ""); if ($prevBackupVersion != $currentBackupVersion) { main::progress("Backup version update required.\n"); Migrate::updateBackupVersion($prevBackupVersion,$currentBackupVersion); main::progress("Backup version update finished.\n"); } } my ($currentMajorBackupVersion,$currentMinorBackupVersion) = split(/\./, $currentBackupVersion); my ($prevMajorBackupVersion,$prevMinorBackupVersion) = split(/\./, $prevBackupVersion); # clear both directories only if the major backup version changed. # backups are backwards compatible between minor versions return if ($prevBackupVersion == $currentBackupVersion); return if ($prevMajorBackupVersion >= $currentMajorBackupVersion); main::progress("Moving /opt/zimbra/backup/* to /opt/zimbra/backup/${startVersion}-${currentBackupVersion}.\n"); clearBackupDir("/opt/zimbra/backup", "${startVersion}-${currentBackupVersion}"); main::progress("Moving /opt/zimbra/redolog/* to /opt/zimbra/redolog/${startVersion}-${currentRedologVersion}.\n"); clearRedologDir("/opt/zimbra/redolog", "${startVersion}-${currentRedologVersion}"); } sub migrateTomcatLCKey { my ($key,$defVal) = @_; $defVal="" unless $defVal; my ($oldKey,$newKey,$oldVal); $oldKey="tomcat_${key}"; $newKey="mailboxd_${key}"; $oldVal = main::getLocalConfig($oldKey); if ($oldVal ne "") { main::setLocalConfig("$newKey", "$oldVal"); } elsif ($defVal ne "") { main::setLocalConfig("$newKey", "$defVal"); } main::deleteLocalConfig("$oldKey"); } sub indexLdap { if (main::isInstalled ("zimbra-ldap")) { stopLdap(); main::runAsZimbra ("/opt/zimbra/libexec/zmslapindex"); if (startLdap()) {return 1;} } return; } sub indexLdapAttribute { my ($key) = @_; if (main::isInstalled ("zimbra-ldap")) { stopLdap(); main::runAsZimbra ("/opt/zimbra/libexec/zmslapindex $key"); if (startLdap()) {return 1;} } return; } sub reloadLdap($) { my ($upgradeVersion) = @_; if (main::isInstalled ("zimbra-ldap")) { if($main::migratedStatus{"LdapReloaded$upgradeVersion"} ne "CONFIGURED") { my $ldifFile="/opt/zimbra/data/ldap/ldap-accesslog.bak"; if (-d '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={3}mdb') { if (-f $ldifFile && -s $ldifFile) { if (-d "/opt/zimbra/data/ldap/accesslog") { main::progress("Loading accesslog DB..."); if (-d "/opt/zimbra/data/ldap/accesslog.prev") { qx(mv /opt/zimbra/data/ldap/accesslog.prev /opt/zimbra/data/ldap/accesslog.prev.$$); } qx(mv /opt/zimbra/data/ldap/accesslog /opt/zimbra/data/ldap/accesslog.prev); qx(mkdir -p /opt/zimbra/data/ldap/accesslog/db); qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap); my $rc; $rc=main::runAsZimbra("/opt/zimbra/libexec/zmslapadd -a $ldifFile"); if ($rc != 0) { main::progress("slapadd import of accesslog db failed.\n"); return 1; } main::progress("done.\n"); } } else { main::progress("Creating new accesslog DB..."); if (-d "/opt/zimbra/data/ldap/accesslog.prev") { qx(mv /opt/zimbra/data/ldap/accesslog.prev /opt/zimbra/data/ldap/accesslog.prev.$$); } qx(mv /opt/zimbra/data/ldap/accesslog /opt/zimbra/data/ldap/accesslog.prev); qx(mkdir -p /opt/zimbra/data/ldap/accesslog/db); qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap); main::progress("done.\n"); } } $ldifFile="/opt/zimbra/data/ldap/ldap.bak"; if (-f $ldifFile && -s $ldifFile) { main::progress("Loading database..."); if (-d "/opt/zimbra/data/ldap/mdb.prev") { qx(mv /opt/zimbra/data/ldap/mdb.prev /opt/zimbra/data/ldap/mdb.prev.$$); } qx(mv /opt/zimbra/data/ldap/mdb /opt/zimbra/data/ldap/mdb.prev); qx(mkdir -p /opt/zimbra/data/ldap/mdb/db); qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap); my $rc; $rc=main::runAsZimbra("/opt/zimbra/libexec/zmslapadd $ldifFile"); if ($rc != 0) { main::progress("slapadd import failed.\n"); return 1; } chmod 0640, $ldifFile; main::progress("done.\n"); } else { if (! -f $ldifFile) { main::progress("Error: Unable to find /opt/zimbra/data/ldap/ldap.bak\n"); } else { main::progress("Error: /opt/zimbra/data/ldap/ldap.bak is empty\n"); } return 1; } main::configLog("LdapUpgraded$upgradeVersion"); } if (startLdap()) {return 1;} } return 0; } sub upgradeLdap($) { my ($upgradeVersion) = @_; if (main::isInstalled ("zimbra-ldap")) { if($upgradeVersion eq "8.7.0_BETA2") { if($main::migratedStatus{"LdapUpgraded$upgradeVersion"} ne "CONFIGURED") { if (-f '/opt/zimbra/data/ldap/config/cn=config/cn=module{0}.ldif') { my $infile="/opt/zimbra/data/ldap/config/cn\=config/cn\=module\{0\}.ldif"; my $outfile="/tmp/mod0.ldif.$$"; open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /^olcModulePath: \/opt\/zimbra\/openldap\/sbin\/openldap/) { print OUT "olcModulePath: \/opt\/zimbra\/common\/libexec\/openldap\n"; next; } if ($_ =~ /^# CRC32/) { next; } print OUT $_; } close(OUT); close(IN); qx(mv $outfile $infile); qx(chown zimbra:zimbra $infile); } main::configLog("LdapUpgraded$upgradeVersion"); } } elsif($upgradeVersion eq "8.5.0_BETA1") { if($main::migratedStatus{"LdapUpgraded$upgradeVersion"} ne "CONFIGURED") { unlink("/opt/zimbra/data/ldap/config/cn\=config/cn\=schema/cn\=\{7\}pgp-keyserver.ldif"); if (-f '/opt/zimbra/data/ldap/config/cn=config.ldif') { my $infile="/opt/zimbra/data/ldap/config/cn\=config.ldif"; my $outfile="/tmp/config.ldif.$$"; open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /^olcPidFile: /) { print OUT "olcPidFile: /opt/zimbra/data/ldap/state/run/slapd.pid\n"; next; } if ($_ =~ /^olcArgsFile: /) { print OUT "olcArgsFile: /opt/zimbra/data/ldap/state/run/slapd.args\n"; next; } if ($_ =~ /^# CRC32/) { next; } print OUT $_; } close(OUT); close(IN); qx(mv $outfile $infile); } if (-f '/opt/zimbra/data/ldap/config/cn=config/cn=module{0}.ldif') { my $infile="/opt/zimbra/data/ldap/config/cn\=config/cn\=module\{0\}.ldif"; my $outfile="/tmp/mod0.ldif.$$"; open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /^olcModulePath: \/opt\/zimbra\/openldap\/sbin\/openldap/) { print OUT "olcModulePath: \/opt\/zimbra\/common\/libexec\/openldap\n"; next; } if ($_ =~ /^# CRC32/) { next; } print OUT $_; } close(OUT); close(IN); qx(mv $outfile $infile); qx(chown zimbra:zimbra $infile); } main::configLog("LdapUpgraded$upgradeVersion"); } } else { if($main::migratedStatus{"LdapUpgraded$upgradeVersion"} ne "CONFIGURED") { # Fix LDAP schema for bug#62443 unlink("/opt/zimbra/data/ldap/config/cn\=config/cn\=schema/cn\=\{3\}zimbra.ldif"); unlink("/opt/zimbra/data/ldap/config/cn\=config/cn\=schema/cn\=\{4\}amavisd.ldif"); unlink("/opt/zimbra/data/ldap/config/cn\=config/cn\=schema/cn\=\{7\}pgp-keyserver.ldif"); my $ldifFile="/opt/zimbra/data/ldap/ldap.bak"; if (-f $ldifFile && -s $ldifFile) { chmod 0644, $ldifFile; my $slapinfile = "$ldifFile"; my $slapoutfile = "/opt/zimbra/data/ldap/ldap.80"; main::progress("Upgrading ldap data..."); open(IN,"<$slapinfile"); open(OUT,">$slapoutfile"); while() { if ($_ =~ /^zimbraChildAccount:/) {next;} if ($_ =~ /^zimbraChildVisibleAccount:/) {next;} if ($_ =~ /^zimbraPrefChildVisibleAccount:/) {next;} if ($_ =~ /^zimbraPrefStandardClientAccessilbityMode:/) {next;} if ($_ =~ /^objectClass: zimbraHsmGlobalConfig/) {next;} if ($_ =~ /^objectClass: zimbraHsmServer/) {next;} if ($_ =~ /^objectClass: organizationalPerson/) { print OUT $_; print OUT "objectClass: inetOrgPerson\n"; next; } if ($_ =~ /^structuralObjectClass: organizationalPerson/) { $_ =~ s/organizationalPerson/inetOrgPerson/; } print OUT $_; } close(IN); close(OUT); main::progress("done.\n"); my $infile; my $outfile; main::progress("Upgrading LDAP configuration database..."); if (-d '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={2}hdb') { qx(mv /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{2\}hdb /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{2\}mdb); } if (-d '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={3}hdb') { qx(mv /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{3\}hdb /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{3\}mdb); $infile=glob("/opt/zimbra/data/ldap/config/cn=config/olcDatabase=\\{3\\}mdb/olcOverlay=\\{*\\}syncprov.ldif"); $outfile="/tmp/3syncprov.ldif.$$"; open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /olcSpSessionlog:/) { next; } if ($_ =~ /^# CRC32/) { next; } print OUT $_; } close(OUT); close(IN); qx(mv $outfile $infile); } if (-f '/opt/zimbra/data/ldap/config/cn=config/cn=module{0}.ldif') { $infile="/opt/zimbra/data/ldap/config/cn\=config/cn\=module\{0\}.ldif"; $outfile="/tmp/mod0.ldif.$$"; open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /^olcModuleLoad: \{0\}back_hdb.la/) { print OUT "olcModuleLoad: {0}back_mdb.la\n"; next; } if ($_ =~ /^olcModulePath: \/opt\/zimbra\/openldap\/sbin\/openldap/) { print OUT "olcModulePath: \/opt\/zimbra\/common\/libexec\/openldap\n"; next; } if ($_ =~ /^# CRC32/) { next; } print OUT $_; } close(OUT); close(IN); qx(mv $outfile $infile); qx(chown zimbra:zimbra $infile); } if (-f '/opt/zimbra/data/ldap/config/cn=config.ldif') { $infile="/opt/zimbra/data/ldap/config/cn\=config.ldif"; $outfile="/tmp/config.ldif.$$"; open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /^olcToolThreads: /) { print OUT "olcToolThreads: 2\n"; next; } if ($_ =~ /^olcPidFile: /) { print OUT "olcPidFile: /opt/zimbra/data/ldap/state/run/slapd.pid\n"; next; } if ($_ =~ /^olcArgsFile: /) { print OUT "olcArgsFile: /opt/zimbra/data/ldap/state/run/slapd.args\n"; next; } if ($_ =~ /^# CRC32/) { next; } print OUT $_; } close(OUT); close(IN); qx(mv $outfile $infile); } if (-f '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={3}hdb.ldif') { qx(mv /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{3\}hdb.ldif /opt/zimbra/data/ldap/config/cn\=config/olcDatabase=\{3\}mdb.ldif); $infile="/opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{3\}mdb.ldif"; $outfile="/tmp/3mdb.ldif.$$"; open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /^dn: olcDatabase=\{3\}hdb/) { print OUT "dn: olcDatabase={3}mdb\n"; next; } if ($_ =~ /^objectClass: olcHdbConfig/) { print OUT "objectClass: olcMdbConfig\n"; next; } if ($_ =~ /^olcDatabase: \{3\}hdb/) { print OUT "olcDatabase: {3}mdb\n"; next; } if ($_ =~ /^olcDbDirectory: \/opt\/zimbra\/data\/ldap\/hdb\/db/) { print OUT "olcDbDirectory: /opt/zimbra/data/ldap/mdb/db\n"; next; } if ($_ =~ /^structuralObjectClass: olcHdbConfig/) { print OUT "structuralObjectClass: olcMdbConfig\n"; next; } if ($_ =~ /^olcDbMode:/) { print OUT $_; print OUT "olcDbMaxsize: 85899345920\n"; next; } if ($_ =~ /^olcDbCheckpoint:/) { print OUT "olcDbCheckpoint: 0 0\n"; print OUT "olcDbEnvFlags: writemap\n"; print OUT "olcDbEnvFlags: nometasync\n"; next; } if ($_ =~ /olcDbNoSync:/) { print OUT "olcDbNoSync: TRUE\n"; next; } if ($_ =~ /olcDbCacheSize:/) { next; } if ($_ =~ /^olcDbConfig:/) { next; } if ($_ =~ /^olcDbDirtyRead:/) { next; } if ($_ =~ /^olcDbIDLcacheSize:/) { next; } if ($_ =~ /^olcDbLinearIndex:/) { next; } if ($_ =~ /^olcDbShmKey:/) { next; } if ($_ =~ /^olcDbCacheFree:/) { next; } if ($_ =~ /^olcDbDNcacheSize:/) { next; } if ($_ =~ /^# CRC32/) { next; } print OUT $_; } close(OUT); close(IN); qx(mv $outfile $infile); } if (-f '/opt/zimbra/data/ldap/config/cn=config/olcDatabase={2}hdb.ldif') { qx(mv /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{2\}hdb.ldif /opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{2\}mdb.ldif); $infile="/opt/zimbra/data/ldap/config/cn\=config/olcDatabase\=\{2\}mdb.ldif"; $outfile="/tmp/2mdb.ldif.$$"; open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /^dn: olcDatabase=\{2\}hdb/) { print OUT "dn: olcDatabase={2}mdb\n"; next; } if ($_ =~ /^objectClass: olcHdbConfig/) { print OUT "objectClass: olcMdbConfig\n"; next; } if ($_ =~ /^olcDatabase: \{2\}hdb/) { print OUT "olcDatabase: {2}mdb\n"; next; } if ($_ =~ /^olcDbDirectory: \/opt\/zimbra\/data\/ldap\/hdb\/db/) { print OUT "olcDbDirectory: /opt/zimbra/data/ldap/mdb/db\n"; next; } if ($_ =~ /^structuralObjectClass: olcHdbConfig/) { print OUT "structuralObjectClass: olcMdbConfig\n"; next; } if ($_ =~ /^olcDbMode:/) { print OUT $_; print OUT "olcDbMaxsize: 85899345920\n"; next; } if ($_ =~ /^olcDbCheckpoint:/) { print OUT "olcDbCheckpoint: 0 0\n"; print OUT "olcDbEnvFlags: writemap\n"; print OUT "olcDbEnvFlags: nometasync\n"; next; } if ($_ =~ /olcDbNoSync:/) { print OUT "olcDbNoSync: TRUE\n"; next; } if ($_ =~ /olcDbCacheSize:/) { next; } if ($_ =~ /^olcDbConfig:/) { next; } if ($_ =~ /^olcDbDirtyRead:/) { next; } if ($_ =~ /^olcDbIDLcacheSize:/) { next; } if ($_ =~ /^olcDbLinearIndex:/) { next; } if ($_ =~ /^olcDbShmKey:/) { next; } if ($_ =~ /^olcDbCacheFree:/) { next; } if ($_ =~ /^olcDbDNcacheSize:/) { next; } if ($_ =~ /^# CRC32/) { next; } print OUT $_; } close(OUT); close(IN); qx(mv $outfile $infile); } main::progress("done.\n"); if (-d "/opt/zimbra/data/ldap/accesslog") { main::progress("Creating new accesslog DB..."); if (-d "/opt/zimbra/data/ldap/accesslog.prev") { qx(mv /opt/zimbra/data/ldap/accesslog.prev /opt/zimbra/data/ldap/accesslog.prev.$$); } qx(mv /opt/zimbra/data/ldap/accesslog /opt/zimbra/data/ldap/accesslog.prev); qx(mkdir -p /opt/zimbra/data/ldap/accesslog/db); qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap); main::progress("done.\n"); } main::progress("Loading database..."); if (-d "/opt/zimbra/data/ldap/mdb.prev") { qx(mv /opt/zimbra/data/ldap/mdb.prev /opt/zimbra/data/ldap/mdb.prev.$$); } qx(mv /opt/zimbra/data/ldap/mdb /opt/zimbra/data/ldap/mdb.prev); qx(mkdir -p /opt/zimbra/data/ldap/mdb/db); qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap); my $rc; $rc=main::runAsZimbra("/opt/zimbra/libexec/zmslapadd $slapoutfile"); if ($rc != 0) { main::progress("slapadd import failed.\n"); return 1; } chmod 0640, $ldifFile; main::progress("done.\n"); } else { if (! -f $ldifFile) { main::progress("Error: Unable to find /opt/zimbra/data/ldap/ldap.bak\n"); } else { main::progress("Error: /opt/zimbra/data/ldap/ldap.bak is empty\n"); } return 1; } main::configLog("LdapUpgraded$upgradeVersion"); } } if (startLdap()) {return 1;} } return 0; } sub migrateLdap($) { my ($migrateVersion) = @_; if (main::isInstalled ("zimbra-ldap")) { if($main::migratedStatus{"LdapUpgraded$migrateVersion"} ne "CONFIGURED") { if (-f "/opt/zimbra/data/ldap/ldap.bak") { my $infile = "/opt/zimbra/data/ldap/ldap.bak"; my $outfile = "/opt/zimbra/data/ldap/ldap.80"; if ( -s $infile ) { open(IN,"<$infile"); open(OUT,">$outfile"); while() { if ($_ =~ /^zimbraChildAccount:/) {next;} if ($_ =~ /^zimbraChildVisibleAccount:/) {next;} if ($_ =~ /^zimbraPrefChildVisibleAccount:/) {next;} if ($_ =~ /^zimbraPrefStandardClientAccessilbityMode:/) {next;} if ($_ =~ /^objectClass: zimbraHsmGlobalConfig/) {next;} if ($_ =~ /^objectClass: zimbraHsmServer/) {next;} if ($_ =~ /^objectClass: organizationalPerson/) { print OUT $_; print OUT "objectClass: inetOrgPerson\n"; next; } if ($_ =~ /^structuralObjectClass: organizationalPerson/) { $_ =~ s/organizationalPerson/inetOrgPerson/; } print OUT $_; } close(IN); close(OUT); } else { main::progress("LDAP backup file /opt/zimbra/data/ldap/ldap.bak is empty.\n"); main::progress("Valid LDAP backup file not found, exiting.\n"); return 1; } chmod 0644, $outfile if ( -s $outfile ); main::installLdapConfig(); main::progress("Migrating ldap data..."); if (-d "/opt/zimbra/data/ldap/mdb.prev") { qx(mv /opt/zimbra/data/ldap/mdb.prev /opt/zimbra/data/ldap/mdb.prev.$$); } qx(mv /opt/zimbra/data/ldap/mdb /opt/zimbra/data/ldap/mdb.prev); qx(mkdir -p /opt/zimbra/data/ldap/mdb/db); qx(chown -R zimbra:zimbra /opt/zimbra/data/ldap); my $rc; $rc=main::runAsZimbra("/opt/zimbra/libexec/zmslapadd $outfile"); if ($rc != 0) { main::progress("slapadd import failed.\n"); return 1; } chmod 0640, "/opt/zimbra/data/ldap/ldap.bak"; main::progress("done.\n"); } else { stopLdap(); main::progress("Running slapindex..."); my $rc = main::runAsZimbra("/opt/zimbra/libexec/zmslapindex"); main::progress(($rc == 0) ? "done.\n" : "failed.\n"); } main::configLog("LdapUpgraded$migrateVersion"); } if (startLdap()) {return 1;} } return 0; } # DeleteLdapTree # Requires Net::LDAP ref and DN # Returns Net::LDAP::Search ref sub DeleteLdapTree { my ($handle, $dn) = @_; # make sure it exists and get all the entries my $result = $handle->search( base => $dn, scope => 'one', filter => "(objectclass=*)"); return $result if ($result->code()); # loop through the entries and recursively delete them foreach my $entry($result->all_entries) { my $ref = DeleteLdapTree($handle, $entry->dn()); return $ref if ($ref->code()); } $result = $handle->delete($dn); return $result; } sub migrateAmavisDB($) { my ($toVersion) = @_; my $amavisdBase = "/opt/zimbra/amavisd-new"; my $toDir = "${amavisdBase}-$toVersion"; main::progress("Migrating amavisd-new to version $toVersion\n"); foreach my $fromVersion (qw(2.5.2 2.4.3 2.4.1 2.3.3 2.3.1)) { next if ($toVersion eq $fromVersion); my $fromDir = "${amavisdBase}-$fromVersion"; main::progress("Checking $fromDir/db\n"); if ( -d "$fromDir/db" && -d "$toDir" && ! -e "$toDir/db/cache.db") { main::progress("Migrating amavis-new db from version $fromVersion to $toVersion\n"); qx(rm -rf $toDir/db > /dev/null 2>&1); qx(mv $fromDir/db $toDir/db); qx(chown zimbra:zimbra $toDir/db); } main::progress("Checking $fromDir/.spamassassin\n"); if (-d "$fromDir/.spamassassin/" && -d "$toDir" && ! -e "$toDir/.spamassassin/bayes_toks" ) { main::progress("Migrating amavis-new .spamassassin from version $fromVersion to $toVersion\n"); qx(rm -rf $toDir/.spamassassin > /dev/null 2>&1); qx(mv $fromDir/.spamassassin $toDir/.spamassassin); qx(chown zimbra:zimbra $toDir/.spamassassin); } } } sub relocateAmavisDB() { my $toDir = "/opt/zimbra/data/amavisd"; my $fromDir = "/opt/zimbra/amavisd-new-2.5.2"; main::progress("Migrating Amavis database directory\n"); if ( -d "$fromDir/db" && -d "$toDir" && ! -e "$toDir/db/cache.db") { qx(rm -rf $toDir/db > /dev/null 2>&1); qx(mv $fromDir/db $toDir/db); qx(chown zimbra:zimbra $toDir/db); } if (-d "$fromDir/.spamassassin/" && -d "$toDir" && ! -e "$toDir/.spamassassain/bayes_toks" ) { qx(rm -rf $toDir/.spamassassin > /dev/null 2>&1); qx(mv $fromDir/.spamassassin $toDir/.spamassassin); qx(chown zimbra:zimbra $toDir/.spamassassin); } } sub verifyDatabaseIntegrity { if (-x "/opt/zimbra/libexec/zmdbintegrityreport") { main::progress("Verifying integrity of databases.\n"); main::runAsZimbra("/opt/zimbra/libexec/zmdbintegrityreport -v -r"); } return; } sub upgradeAllGlobalAdminAccounts { my @admins = qx($su "$ZMPROV gaaa"); main::detail("Upgrading ACLs for all admin accounts.\n"); my @adminUpgrades; foreach my $admin (@admins) { chomp $admin; my $val = main::getLdapAccountValue("zimbraIsAdminAccount",$admin); if (lc($val) eq "true") { push(@adminUpgrades,$admin); next; } } main::progress("Upgrading global admin accounts..."); my $wfh= new FileHandle; my $efh= new FileHandle; my @errors; main::detail("Executing $su $ZMPROV"); if (my $pid = open3($wfh,undef,$efh,"$su \"$ZMPROV\"")) { foreach my $admin (@adminUpgrades) { main::detail("$ZMPROV ma $admin zimbraAdminConsoleUIComponents cartBlancheUI"); print $wfh "ma $admin zimbraAdminConsoleUIComponents cartBlancheUI\n"; } print $wfh "exit\n"; @errors = <$efh>; main::detail("@errors") if (scalar(@errors) != 0) ; close($wfh); close($efh); waitpid $pid, 0; } main::progress(($? == 0 && scalar(@errors) == 0) ? "done.\n" : "failed.\n"); } sub upgradeLdapConfigValue($$$) { my ($key,$new_value,$cmp_value) = @_; my $current_value = main::getLdapConfigValue($key); if ($new_value eq "") { $new_value="\'\'"; } main::setLdapGlobalConfig($key, $new_value) if ($current_value eq $cmp_value); } sub addLdapIndex($$$) { my ($index, $type) = @_; my $ldap_pass = qx($su "zmlocalconfig -s -m nokey ldap_root_password"); chomp($ldap_pass); my $ldap; unless($ldap = Net::LDAP->new('ldapi://%2fopt%2fzimbra%2fdata%2fldap%2fstate%2frun%2fldapi/')) { main::progress("Unable to connect to ldapi: $!\n"); } my $result = $ldap->bind("cn=config", password => $ldap_pass); my $dn="olcDatabase={2}mdb,cn=config"; if ($isLdapMaster) { $result = $ldap->search( base=> "cn=accesslog", filter=>"(objectClass=*)", scope => "base", attrs => ['1.1'], ); my $size = $result->count; if ($size > 0 ) { $dn="olcDatabase={3}mdb,cn=config"; } } $result = $ldap->search( base=> "$dn", filter=>"(objectClass=*)", scope => "base", attrs => ['olcDbIndex'], ); my $entry=$result->entry($result->count-1); my @attrvals=$entry->get_value("olcDbIndex"); my $hasIndex=0; foreach my $attr (@attrvals) { if ($attr =~ /$index/) { $hasIndex=1; } } if (!$hasIndex) { $result = $ldap->modify( $dn, add =>{olcDbIndex=>"$index $type"}, ); } $ldap->unbind; return !$hasIndex; } sub upgradeLocalConfigValue($$$) { my ($key,$new_value,$cmp_value) = @_; my $current_value = main::getLocalConfig($key); main::setLocalConfig("$key", "$new_value") if ($current_value eq $cmp_value); } sub runAttributeUpgrade($) { my ($startVersion) = @_; my $rc = main::runAsZimbra("zmjava com.zimbra.cs.account.ldap.upgrade.LdapUpgrade -b 27075 -v $startVersion"); return $rc; } sub runLdapAttributeUpgrade($) { my ($bug) = @_; return if ($bug eq ""); my $rc = main::runAsZimbra("zmjava com.zimbra.cs.account.ldap.upgrade.LdapUpgrade -b $bug -v"); return $rc; } 1; ================================================ FILE: show_git_overrides.sh ================================================ #!/bin/bash if [ $# -lt 1 ] then echo "Usage: $0 [remote-branch]" exit 1 fi CDPATH= SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" main() { local CFG="$1"; shift; local BR="$1"; shift; local i for i in $SCRIPT_DIR/../* do if [ -d "$i/.git" ]; then ( cd $i; _J=$( git fetch --all ) if [ "$BR" ] then LOCAL_BRANCH=$( git branch -r | grep -w "$BR" | grep -v -e '->' | sed -e 's,^\s*,,' -e 's,/, ,' | head -1 | awk '{ print $2 }') REMOTE_BRANCH=$LOCAL_BRANCH REMOTE_NAME= REMOTE_URL= REPO_NAME=$(git remote -v | awk '{ print $2; exit; }' | xargs -n1 '-I{}' -- basename '{}' .git) else LOCAL_BRANCH=$( git branch -vv | grep '^[*]' | sed -e 's/no branch/no-branch/' | awk '{ print $2 }') REMOTE_BRANCH=$(git branch -vv | grep '^[*]' | grep -o '\[[^]]*\]' | sed -e 's,:.*\],],' -e 's,^.,,' -e 's,\]$,,' -e 's,[^/]*/,,') REMOTE_NAME=$( git branch -vv | grep '^[*]' | grep -o '\[[^]]*\]' | sed -e 's,:.*\],],' -e 's,^.,,' -e 's,\]$,,' -e 's,/.*,,') REMOTE_URL=$( git remote get-url "$REMOTE_NAME" 2>/dev/null) REPO_NAME=$(basename "$REMOTE_URL" .git) fi if [ "$LOCAL_BRANCH" == "(no-branch)" ] || [ -z "$LOCAL_BRANCH" ] || [ -z "$REPO_NAME" ] then continue fi if [ "$LOCAL_BRANCH" != "develop" ] then if [ "$CFG" == "cfg" ] then echo "%GIT_OVERRIDES = ${REPO_NAME}.branch=$LOCAL_BRANCH" else echo "--git-overrides ${REPO_NAME}.branch=$LOCAL_BRANCH" fi fi if [ "$LOCAL_BRANCH" != "$REMOTE_BRANCH" ] && [ "$REMOTE_BRANCH" != "develop" ] then if [ "$CFG" == "cfg" ] then echo "%GIT_OVERRIDES = ${REPO_NAME}.branch=$REMOTE_BRANCH" else echo "# --git-overrides ${REPO_NAME}.branch=$REMOTE_BRANCH" fi fi if [ "$REMOTE_URL" ] then if ! grep -q -e "/Zimbra" -e ":Zimbra" -e "/zimbra/" <(echo "$REMOTE_URL") then if [ "$CFG" == "cfg" ] then echo "%GIT_OVERRIDES = ${REPO_NAME}.remote=my-${REPO_NAME}-rem" echo "%GIT_OVERRIDES = my-${REPO_NAME}-rem.url-prefix=$REMOTE_URL" else echo "--git-overrides ${REPO_NAME}.remote=my-${REPO_NAME}-rem" echo "--git-overrides my-${REPO_NAME}-rem.url-prefix=$REMOTE_URL" fi fi fi ) fi done } main "$@"