steffen: server/kolabd/kolabd Makefile.am, NONE, 1.1 Makefile.in, NONE, 1.1 bootstrap, NONE, 1.1 configure.ac, NONE, 1.1 kolab.in, NONE, 1.1 kolab_bootstrap.in, NONE, 1.1 kolab_ca.sh.in, NONE, 1.1 kolab_smtpdpolicy.in, NONE, 1.1 kolab_sslcert.sh.in, NONE, 1.1 kolabcheckperm.in, NONE, 1.1 kolabconf.in, NONE, 1.1 kolabd.in, NONE, 1.1 kolabd.spec.in, NONE, 1.1 kolabpasswd.in, NONE, 1.1 kolabquotawarn.in, NONE, 1.1 rc.kolabd.in, NONE, 1.1 workaround.sh.in, NONE, 1.1 kolab, 1.1.1.1, NONE kolab_bootstrap, 1.18, NONE kolab_ca.sh, 1.1.1.1, NONE kolab_smtpdpolicy, 1.6, NONE kolab_sslcert.sh, 1.1.1.1, NONE kolabcheckperm, 1.1, NONE kolabconf, 1.3, NONE kolabd, 1.2, NONE kolabpasswd, 1.7, NONE kolabquotawarn, 1.5, NONE workaround.sh, 1.1.1.1, NONE

cvs at intevation.de cvs at intevation.de
Tue Sep 13 16:38:24 CEST 2005


Author: steffen

Update of /kolabrepository/server/kolabd/kolabd
In directory doto:/tmp/cvs-serv22600/kolabd

Added Files:
	Makefile.am Makefile.in bootstrap configure.ac kolab.in 
	kolab_bootstrap.in kolab_ca.sh.in kolab_smtpdpolicy.in 
	kolab_sslcert.sh.in kolabcheckperm.in kolabconf.in kolabd.in 
	kolabd.spec.in kolabpasswd.in kolabquotawarn.in rc.kolabd.in 
	workaround.sh.in 
Removed Files:
	kolab kolab_bootstrap kolab_ca.sh kolab_smtpdpolicy 
	kolab_sslcert.sh kolabcheckperm kolabconf kolabd kolabpasswd 
	kolabquotawarn workaround.sh 
Log Message:
kolabd autoconfiscated!

--- NEW FILE: Makefile.am ---
EXTRA_DIST = 
CLEANFILES =

@distribution@
@common@

noinst_HEADERS = @PACKAGE at .spec

# is sometimes used in this file
kolabconfdir = $(sysconfdir)/kolab

kolabdir = $(sysconfdir)/kolab
dist_kolab_SCRIPTS = \
	kolab_sslcert.sh \
	kolab_ca.sh \
	kolab kolab_bootstrap \
	workaround.sh \
	kolabquotawarn \
	kolab_smtpdpolicy 


kolabconfig_FILES = kolab.conf \
	kolab.globals \
	rootDSE.ldif \
	quotawarning.txt

kolabconfigdir = $(kolabconfdir)
dist_kolabconfig_DATA = $(kolabconfig_FILES)


kolabtemplate_FILES = templates/amavisd.conf.template \
	templates/clamd.conf.template \
	templates/cyrus.conf.template \
	templates/DB_CONFIG.slapd.template \
	templates/fbview.conf.template \
	templates/freebusy.conf.template \
	templates/freshclam.conf.template \
	templates/httpd.conf.template \
	templates/httpd.local.template \
	templates/imapd.conf.template \
	templates/imapd.group.template \
	templates/kolab.conf.template \
	templates/ldap.conf.template \
	templates/main.cf.template \
	templates/master.cf.template \
	templates/php.ini.template \
	templates/proftpd.conf.template \
	templates/rc.conf.template \
	templates/resmgr.conf.template \
	templates/saslauthd.conf.template \
	templates/session_vars.php.template \
	templates/slapd.access.template \
	templates/slapd.conf.template \
	templates/slapd.replicas.template \
	templates/smtpd.conf.template \
	templates/transport.template \
	templates/virtual.template

kolabtemplatedir = $(kolabconfdir)/templates
kolabtemplate_DATA = $(kolabtemplate_FILES)


kolabnamespace_FILES = namespace/libexec/newconfig \
	namespace/libexec/adduser \
	namespace/libexec/deluser \
	namespace/libexec/listusers \
	namespace/libexec/showuser \
	namespace/libexec/newconfig \
	namespace/libexec/services \
	namespace/libexec/showlog \
	namespace/libexec/start \
	namespace/libexec/stop 

kolabnamespacedir = $(libexecdir)/kolab
kolabnamespace_DATA = $(kolabnamespace_FILES)
EXTRA_DIST += namespace/libexec/start
EXTRA_DIST += namespace/libexec/stop

ldapschema_FILES =  kolab2.schema \
	rfc2739.schema

ldapschemadir = $(ldapconfdir)/schema
dist_ldapschema_DATA = $(ldapschema_FILES)


amavisdus_FILES = amavisd/en_US/charset \
	amavisd/en_US/template-dsn.txt \
	amavisd/en_US/template-spam-admin.txt \
	amavisd/en_US/template-spam-sender.txt \
	amavisd/en_US/template-virus-admin.txt \
	amavisd/en_US/template-virus-recipient.txt \
	amavisd/en_US/template-virus-sender.txt

amavisdusdir = $(amavisdconfdir)/templates/en_US
dist_amavisdus_DATA = $(amavisdus_FILES)


amavisdde_FILES = amavisd/de/charset \
	amavisd/de/template-dsn.txt \
	amavisd/de/template-spam-admin.txt \
	amavisd/de/template-spam-sender.txt \
	amavisd/de/template-virus-admin.txt \
	amavisd/de/template-virus-recipient.txt \
	amavisd/de/template-virus-sender.txt

amavisddedir = $(amavisdconfdir)/templates/de
dist_amavisdde_DATA = $(amavisdde_FILES)


kolabdoc_FILES = doc/README.amavisd \
	doc/README.ldapdelete \
	doc/README.outlook \
	doc/README.sieve \
	doc/README.webgui

kolabdocdir = $(datadir)/kolab/doc
dist_kolabdoc_DATA = $(kolabdoc_FILES)

kolabsbin_FILES =  kolabd \
	kolabconf \
	kolabcheckperm

kolabsbindir = $(sbindir)/
kolabsbin_DATA = $(kolabsbin_FILES)
EXTRA_DIST += kolabcheckperm


kolabbin_FILE = namespace/kolab \
	kolabpasswd

kolabbindir = $(bindir)
dist_kolabbin_DATA = $(kolabbin_FILE)


kolabrc_FILE = rc.kolabd

# that works - but $(rcdir) not :/
kolabrcdir = $(sysconfdir)/rc.d

dist_kolabrc_DATA = $(kolabrc_FILE)

#srcdir = .

kolab:
	@$(mkinstalldirs) .
	$(do_subst) <$(srcdir)/kolab.in >$@
	chmod a+x kolab
CLEANFILES += kolab
EXTRA_DIST += kolab.in

#kolab2.schema:
#	@$(mkinstalldirs) .
#	 $(do_subst) <$(srcdir)/kolab2.schema.in >$@
#CLEANFILES += kolab2.schema
#EXTRA_DIST += kolab2.schema.in

kolab_ca.sh:
	@$(mkinstalldirs) .
	 $(do_subst) <$(srcdir)/kolab_ca.sh.in >$@
	 chmod a+x kolab_ca.sh
CLEANFILES += kolab_ca.sh
EXTRA_DIST += kolab_ca.sh.in

kolab_bootstrap:
	@$(mkinstalldirs) .
	$(do_subst) <$(srcdir)/kolab_bootstrap.in >$@
	chmod a+x kolab_bootstrap
CLEANFILES += kolab_bootstrap
EXTRA_DIST += kolab_bootstrap.in

kolab_sslcert.sh:
	@$(mkinstalldirs) .
	$(do_subst) <$(srcdir)/kolab_sslcert.sh.in >$@
	chmod a+x kolab_sslcert.sh
CLEANFILES += kolab_sslcert.sh
EXTRA_DIST += kolab_sslcert.sh.in

kolabconf:
	@$(mkinstalldirs) .
	 $(do_subst) <$(srcdir)/kolabconf.in >$@
	 chmod a+x kolabconf
CLEANFILES += kolabconf
EXTRA_DIST += kolabconf.in

kolabcheckperm:
	@$(mkinstalldirs) .
	$(do_subst) <$(srcdir)/kolabcheckperm.in >$@
CLEANFILES += kolabcheckperm
EXTRA_DIST += kolabcheckperm.in

kolabd:
	@$(mkinstalldirs) .
	 $(do_subst) <$(srcdir)/kolabd.in >$@
	 chmod a+x kolabd
CLEANFILES += kolabd
EXTRA_DIST += kolabd.in

kolabpasswd:
	@$(mkinstalldirs) .
	 $(do_subst) <$(srcdir)/kolabpasswd.in >$@
	 chmod a+x kolabpasswd
CLEANFILES += kolabpasswd
EXTRA_DIST += kolabpasswd.in

kolabquotawarn:
	@$(mkinstalldirs) .
	 $(do_subst) <$(srcdir)/kolabquotawarn.in >$@
	 chmod a+x kolabquotawarn
CLEANFILES += kolabquotawarn
EXTRA_DIST += kolabquotawarn.in

#namespace/kolab:
#	@$(mkinstalldirs) namespace/
#	 $(do_subst) <$(srcdir)/namespace/kolab.in >$@
#CLEANFILES += namespace/kolab
#EXTRA_DIST += namespace/kolab.in

namespace/libexec/adduser:
	@$(mkinstalldirs) namespace/libexec
	 $(do_subst) <$(srcdir)/namespace/libexec/adduser.in >$@
	 chmod a+x namespace/libexec/adduser
CLEANFILES += namespace/libexec/adduser
EXTRA_DIST += namespace/libexec/adduser.in

namespace/libexec/deluser:
	@$(mkinstalldirs) namespace/libexec
	$(do_subst) <$(srcdir)/namespace/libexec/deluser.in >$@
	chmod a+x namespace/libexec/deluser
CLEANFILES += namespace/libexec/deluser
EXTRA_DIST += namespace/libexec/deluser.in

namespace/libexec/listusers:
	@$(mkinstalldirs) namespace/libexec
	$(do_subst) <$(srcdir)/namespace/libexec/listusers.in >$@
	chmod a+x namespace/libexec/listusers
CLEANFILES += namespace/libexec/listusers
EXTRA_DIST += namespace/libexec/listusers.in

namespace/libexec/newconfig:
	@$(mkinstalldirs) namespace/libexec
	$(do_subst) <$(srcdir)/namespace/libexec/newconfig.in >$@
	chmod a+x namespace/libexec/newconfig
CLEANFILES += namespace/libexec/newconfig
EXTRA_DIST += namespace/libexec/newconfig.in

namespace/libexec/services:
	@$(mkinstalldirs) namespace/libexec
	$(do_subst) <$(srcdir)/namespace/libexec/services.in >$@
	chmod a+x namespace/libexec/services
CLEANFILES += namespace/libexec/services
EXTRA_DIST += namespace/libexec/services.in

namespace/libexec/showlog:
	@$(mkinstalldirs) namespace/libexec
	$(do_subst) <$(srcdir)/namespace/libexec/showlog.in >$@
	chmod a+x namespace/libexec/showlog
CLEANFILES += namespace/libexec/showlog
EXTRA_DIST += namespace/libexec/showlog.in

namespace/libexec/showuser:
	@$(mkinstalldirs) namespace/libexec
	$(do_subst) <$(srcdir)/namespace/libexec/showuser.in >$@
	chmod a+x namespace/libexec/showuser
CLEANFILES += namespace/libexec/showuser
EXTRA_DIST += namespace/libexec/showuser.in

namespace/libexec/start:
	@$(mkinstalldirs) namespace/libexec
	$(do_subst) <$(srcdir)/namespace/libexec/start.in >$@
	chmod a+x namespace/libexec/start
CLEANFILES += namespace/libexec/start
EXTRA_DIST += namespace/libexec/start.in

namespace/libexec/stop:
	@$(mkinstalldirs) namespace/libexec
	$(do_subst) <$(srcdir)/namespace/libexec/stop.in >$@
	chmod a+x namespace/libexec/stop
CLEANFILES += namespace/libexec/stop
EXTRA_DIST += namespace/libexec/stop.in

namespace/kolab:
	@$(mkinstalldirs) namespace/
	$(do_subst) <$(srcdir)/namespace/kolab.in >$@
	chmod a+x namespace/kolab
CLEANFILES += namespace/kolab
EXTRA_DIST += namespace/kolab.in

templates/clamd.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/clamd.conf.template.in >$@
CLEANFILES += templates/clamd.conf.template
EXTRA_DIST += templates/clamd.conf.template.in

templates/cyrus.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/cyrus.conf.template.in >$@
CLEANFILES += templates/cyrus.conf.template
EXTRA_DIST += templates/cyrus.conf.template.in

templates/DB_CONFIG.slapd.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/DB_CONFIG.slapd.template.in >$@
CLEANFILES += templates/DB_CONFIG.slapd.template
EXTRA_DIST += templates/DB_CONFIG.slapd.template.in

templates/fbview.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/fbview.conf.template.in >$@
CLEANFILES += templates/fbview.conf.template
EXTRA_DIST += templates/fbview.conf.template.in

templates/freebusy.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/freebusy.conf.template.in >$@
CLEANFILES += templates/freebusy.conf.template
EXTRA_DIST += templates/freebusy.conf.template.in

templates/freshclam.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/freshclam.conf.template.in >$@
CLEANFILES += templates/freshclam.conf.template
EXTRA_DIST += templates/freshclam.conf.template.in

templates/httpd.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/httpd.conf.template.in >$@
CLEANFILES += templates/httpd.conf.template
EXTRA_DIST += templates/httpd.conf.template.in

templates/httpd.local.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/httpd.local.template.in >$@
CLEANFILES += templates/httpd.local.template
EXTRA_DIST += templates/httpd.local.template.in

templates/imapd.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/imapd.conf.template.in >$@
CLEANFILES += templates/imapd.conf.template
EXTRA_DIST += templates/imapd.conf.template.in

templates/imapd.group.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/imapd.group.template.in >$@
CLEANFILES += templates/imapd.group.template
EXTRA_DIST += templates/imapd.group.template.in

templates/kolab.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/kolab.conf.template.in >$@
CLEANFILES += templates/kolab.conf.template
EXTRA_DIST += templates/kolab.conf.template.in

templates/ldap.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/ldap.conf.template.in >$@
CLEANFILES += templates/ldap.conf.template
EXTRA_DIST += templates/ldap.conf.template.in

templates/ldapdistlist.cf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/ldapdistlist.cf.template.in >$@
CLEANFILES += templates/ldapdistlist.cf.template
EXTRA_DIST += templates/ldapdistlist.cf.template.in

templates/ldaptransport.cf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/ldaptransport.cf.template.in >$@
CLEANFILES += templates/ldaptransport.cf.template
EXTRA_DIST += templates/ldaptransport.cf.template.in

templates/ldapvirtual.cf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/ldapvirtual.cf.template.in >$@
CLEANFILES += templates/ldapvirtual.cf.template
EXTRA_DIST += templates/ldapvirtual.cf.template.in

templates/main.cf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/main.cf.template.in >$@
CLEANFILES += templates/main.cf.template
EXTRA_DIST += templates/main.cf.template.in

templates/master.cf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/master.cf.template.in >$@
CLEANFILES += templates/master.cf.template
EXTRA_DIST += templates/master.cf.template.in

templates/php.ini.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/php.ini.template.in >$@
CLEANFILES += templates/php.ini.template
EXTRA_DIST += templates/php.ini.template.in

templates/proftpd.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/proftpd.conf.template.in >$@
CLEANFILES += templates/proftpd.conf.template
EXTRA_DIST += templates/proftpd.conf.template.in

templates/rc.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/rc.conf.template.in >$@
CLEANFILES += templates/rc.conf.template
EXTRA_DIST += templates/rc.conf.template.in

templates/resmgr.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/resmgr.conf.template.in >$@
CLEANFILES += templates/resmgr.conf.template
EXTRA_DIST += templates/resmgr.conf.template.in

templates/saslauthd.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/saslauthd.conf.template.in >$@
CLEANFILES += templates/saslauthd.conf.template
EXTRA_DIST += templates/saslauthd.conf.template.in

templates/session_vars.php.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/session_vars.php.template.in >$@
CLEANFILES += templates/session_vars.php.template
EXTRA_DIST += templates/session_vars.php.template.in

templates/slapd.access.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/slapd.access.template.in >$@
CLEANFILES += templates/slapd.access.template
EXTRA_DIST += templates/slapd.access.template.in

templates/slapd.conf.template:
	@$(mkinstalldirs) templtes
	$(do_subst) <$(srcdir)/templates/slapd.conf.template.in >$@
CLEANFILES += templates/slapd.conf.template
EXTRA_DIST += templates/slapd.conf.template.in

templates/slapd.replicas.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/slapd.replicas.template.in >$@
CLEANFILES += templates/slapd.replicas.template
EXTRA_DIST += templates/slapd.replicas.template.in

templates/smtpd.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/smtpd.conf.template.in >$@
CLEANFILES += templates/smtpd.conf.template
EXTRA_DIST += templates/smtpd.conf.template.in

templates/transport.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/transport.template.in >$@
CLEANFILES += templates/transport.template
EXTRA_DIST += templates/transport.template.in

templates/virtual.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/virtual.template.in >$@
CLEANFILES += templates/virtual.template
EXTRA_DIST += templates/virtual.template.in

templates/amavisd.conf.template:
	@$(mkinstalldirs) templates
	$(do_subst) <$(srcdir)/templates/amavisd.conf.template.in >$@
CLEANFILES += templates/amavisd.conf.template
EXTRA_DIST += templates/amavisd.conf.template.in

workaround.sh:
	@$(mkinstalldirs) .
	 $(do_subst) <$(srcdir)/workaround.sh.in >$@
	 chmod a+x workaround.sh
CLEANFILES += workaround.sh
EXTRA_DIST += workaround.sh.in

kolab_smtpdpolicy:
	@$(mkinstalldirs) .
	$(do_subst) <$(srcdir)/kolab_smtpdpolicy.in >$@
	chmod a+x kolab_smtpdpolicy
CLEANFILES += kolab_smtpdpolicy
EXTRA_DIST += kolab_smtpdpolicy.in

doc/README.amavisd:
	@$(mkinstalldirs) doc
	$(do_subst) <$(srcdir)/doc/README.amavisd.in >$@
CLEANFILES += doc/README.amavisd
EXTRA_DIST += doc/README.amavisd.in

doc/README.webgui:
	@$(mkinstalldirs) doc
	$(do_subst) <$(srcdir)/doc/README.webgui.in >$@
CLEANFILES += doc/README.webgui
EXTRA_DIST += doc/README.webgui.in

rc.kolabd:
	@$(mkinstalldirs) .
	$(do_subst) <$(srcdir)/rc.kolabd.in >$@
CLEANFILES += rc.kolabd
EXTRA_DIST += rc.kolabd.in


EXTRA_DIST += dist_conf kolabd.spec.in

install-data-hook:
	$(mkinstalldirs) -m 755 $(DESTDIR)
	$(mkinstalldirs) -m 755 $(DESTDIR)$(kolab_logdir)
	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_document_root)/cgi-bin
	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_document_root)/icons
	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_document_root)/freebusy
	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_sessions)
#	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_document_root)/locks
	chmod +775 $(DESTDIR)$(kolabdir)$(kolab_FILES)
	chmod +600 $(DESTDIR)$(kolabconfigdir)/kolab.conf
	chmod +744 $(DESTDIR)$(kolabnamespacedir)/*
	chmod +744 $(DESTDIR)$(sbindir)/kolabd
	chmod +744 $(DESTDIR)$(sbindir)/kolabconf
	chmod +744 $(DESTDIR)$(sbindir)/kolabcheckperm
	chmod +755 $(DESTDIR)$(kolabrcdir)/$(kolabrc_FILE)
	chmod +744 $(DESTDIR)$(bindir)/kolab
	chmod +755 $(DESTDIR)$(bindir)/kolabpasswd


--- NEW FILE: Makefile.in ---
# Makefile.in generated by automake 1.9.5 from Makefile.am.
# @configure_input@

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005  Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.

@SET_MAKE@



srcdir = @srcdir@
[...1093 lines suppressed...]
install-data-hook:
	$(mkinstalldirs) -m 755 $(DESTDIR)
	$(mkinstalldirs) -m 755 $(DESTDIR)$(kolab_logdir)
	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_document_root)/cgi-bin
	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_document_root)/icons
	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_document_root)/freebusy
	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_sessions)
#	$(mkinstalldirs) -m 755 $(DESTDIR)$(webserver_document_root)/locks
	chmod +775 $(DESTDIR)$(kolabdir)$(kolab_FILES)
	chmod +600 $(DESTDIR)$(kolabconfigdir)/kolab.conf
	chmod +744 $(DESTDIR)$(kolabnamespacedir)/*
	chmod +744 $(DESTDIR)$(sbindir)/kolabd
	chmod +744 $(DESTDIR)$(sbindir)/kolabconf
	chmod +744 $(DESTDIR)$(sbindir)/kolabcheckperm
	chmod +755 $(DESTDIR)$(kolabrcdir)/$(kolabrc_FILE)
	chmod +744 $(DESTDIR)$(bindir)/kolab
	chmod +755 $(DESTDIR)$(bindir)/kolabpasswd
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

--- NEW FILE: bootstrap ---
touch NEWS README AUTHORS ChangeLog
#cp -R ../../perl-kolab/dist_conf .
autoreconf -f -i


--- NEW FILE: configure.ac ---
AC_PREREQ(2.59)

# not the real version
m4_define(_VERSION,2.0.0)
AC_INIT([kolabd],[_VERSION],[kolab-devel at kolab.org])
AC_CONFIG_AUX_DIR(.)

AM_INIT_AUTOMAKE([gnu] [1.7] [dist-bzip2])
AC_PREFIX_DEFAULT([/usr])

common=dist_conf/common
AC_SUBST_FILE(common)

AC_ARG_ENABLE([dist],
  [AC_HELP_STRING([--enable-dist=DIST],
     [distribution target (default: openpkg)])],
     [distribution=dist_conf/$enable_dist],
   [distribution=dist_conf/kolab])
AC_SUBST_FILE(distribution)

AC_ARG_ENABLE([ldapconfdir],
  [AC_HELP_STRING([--enable-ldapconfdir=DIR],
  	 [The LDAP configuration dir (default: SYSCONFDIR/openldap)])],
  [ldapconfdir="$enable_ldapconfdir"],
  [ldapconfdir="\$(sysconfdir)/openldap"])
AC_SUBST(ldapconfdir)

AC_ARG_ENABLE([amavasdconfdir],
  [AC_HELP_STRING([--enable-amavisdconfdir=DIR],
    [The amavisd configuration dir (default: SYSCONFDIR/amavisd)])],
  [amavisdconfdir="$enable_amavisdconfdir"],
  [amavisdconfdir="\$(sysconfdir)/amavisd"])
AC_SUBST(amavisdconfdir)  

# Checks for libraries.

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

# Build date for spec file
spec_build_date=`date '+%Y%m%d'`
AC_SUBST(spec_build_date)

AC_CONFIG_FILES([
Makefile
kolabd.spec
])

AC_OUTPUT


--- NEW FILE: kolab.in ---
#!@perl_exec@

##
##  Copyright (c) 2003  Code Fusion cc
##
##    Writen by Stuart Bingë  <s.binge at codefusion.co.za>
##    Portions based on work by the following people:
##
##      (c) 2003  Tassilo Erlewein  <tassilo.erlewein at erfrakon.de>
##      (c) 2003  Martin Konold     <martin.konold at erfrakon.de>
##      (c) 2003  Achim Frank       <achim.frank at erfrakon.de>
##
##
##  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; either version 2, or
##  (at your option) any later version.
##
##  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 can view the  GNU General Public License, online, at the GNU
##  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
##

use strict;
use Getopt::Std;
use vars qw($opt_o);

getopts('vol:');

if ($opt_o) {
    print "NOTE: USE OF THIS SCRIPT IS DEPRECATED. Please use `@sbindir@/kolabconf' in the future.\n";
    system("@sbindir@/kolabconf");
} else {
    print "NOTE: USE OF THIS SCRIPT IS DEPRECATED. Please use `@sbindir@/kolabd' in the future.\n";
    system("@sbindir@/kolabd");
}

--- NEW FILE: kolab_bootstrap.in ---
#!@perl_exec@

# (c) 2004 Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
# (c) 2003,2004 Tassilo Erlewein <tassilo.erlewein at erfrakon.de>
# (c) 2003-2005 Martin Konold <martin.konold at erfrakon.de>
# (c) 2003 Achim Frank <achim.frank at erfrakon.de>
#
# This program is Free Software under the GNU General Public License (>=v2).
# Read the file COPYING that comes with this packages for details.

# kolab_bootstrap Version 0.93

use strict;
use vars qw($opt_b $opt_f);

use URI;
use Socket;
use IO::File;
use IO::Select;
use Net::LDAP;
use Net::LDAP::Entry;
use Net::Netmask;
use File::Copy;
use Getopt::Std;
use Sys::Hostname;
use Term::ReadKey;
use Time::Local;
use Time::localtime;

my $kolab_prefix = "@prefix@";
my $kolab_config = "@sysconfdir@/kolab/kolab.conf";
my %kolab_config;

##### Utility Functions

# Try to get fqdn
sub myhostname {
  my $host = '';
  # FIXME: hardcoded - maybe fixed later
  if( open( HOSTNAME, '/etc/HOSTNAME' ) ) {
    $host = <HOSTNAME>;
    chomp $host;
    close( HOSTNAME );
  }
  # FIXME: hardcoded - maybe fixed later  
  if( open( HOSTNAME, '/etc/hostname' ) ) {
    $host = <HOSTNAME>;
    chomp $host;
    close( HOSTNAME );
  }
  if( $host eq '' ) {
    $host = `hostname`;
  }
  return $host;
}

# Connect to host,port and return 1 on success
sub tryConnect {
  my $host  = shift;
  my $port    = shift;
  if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') }
  die "No port" unless $port;
  my $iaddr   = inet_aton($host)               || die "no host: $host";
  my $paddr   = sockaddr_in($port, $iaddr);
  my $proto   = getprotobyname('tcp');
  socket(SOCK, PF_INET, SOCK_STREAM, $proto)  || die "socket: $!";
  my $retval = connect(SOCK, $paddr) || 0;
  close( SOCK );
  return $retval;
}

# Check for running service
sub checkPort {
  my $name = shift; # Name of the service e.g. webserver
  my $port = shift; # tcp Port of the named service
  print ("Check for running $name on port $port\n");
  if (tryConnect("localhost",$port) == 1) {
    print ("Error: Found $name running on Port $port\n");
    print ("Check your installation!\n");
    print ("You must stop the service $name before running Kolab\n");
    print ("You may try to execute \"$kolab_prefix/bin/openpkg rc all stop\" initially\n");
    exit 1;
  }
}

# Hash a password
sub hashPassword {
  my $pw = shift;
  my $hashcmd = "@sbindir@/slappasswd -s '".$pw."'";
  (my $hashpw = `$hashcmd`) or die $@;
  chomp($hashpw);
  return $hashpw;
}

# Ask the user a question
sub getUserInput {
  my $text = shift;
  my $default = shift;
  my @values = @_;

  if( $default ) {
        $text = "$text [$default]";
  }
  if( @values ) {
        $text = "$text (".join('/', @values)."): ";
  } else {
        $text = "$text: ";
  }
AGAIN:
  print $text;
  my $tmp = ReadLine;
  chomp $tmp;
  if( $default && $tmp eq '' ) { $tmp = $default; }
  if( @values ) {
    foreach( @values ) { return $tmp if( $tmp eq $_ ); }
    goto AGAIN;
  }
  return $tmp;
}

# Like system() but echo the line before executing
sub kolab_system {
  my $arg = shift;
  print "$arg\n";
  system( $arg ) == 0
    or die "system $arg failed: $?";
};

# Usable chown
sub kolab_chown {
    my $u = shift;
    my $g = shift;
    my $uid = getpwnam($u);
    my $gid = getgrnam($g);
    while( my $file = shift ) {
	chown $uid,$gid,$file;
    }
}

# Fetch entry from ldap server or create new entry of none exist
sub newOrExistingLDAPEntry {
  my $ldap = shift;
  my $dn = shift;

  my $mesg = $ldap->search( base => $dn, scope => 'exact', filter => '(objectClass=*)' );
  if( $mesg && $mesg->count() > 0 ) {
    return $mesg->entry(0);
  } else {
    return Net::LDAP::Entry->new;
  }
}

sub newkolabgroupofnames {
  my $ldap = shift;
  my $basedn = shift;
  my $cn = shift;

  if( scalar(@_) < 1 ) {
    warn "kolabgroupofnames must contain at least one member";
  }

  my $ldapobject = newOrExistingLDAPEntry($ldap,"cn=$cn,$basedn");
  $ldapobject->replace('cn' => $cn, 'objectclass' => ['top','kolabgroupofnames'],
		       'member' => @_);
  $ldapobject->dn("cn=$cn,$basedn");
  my $mesg = $ldapobject->update($ldap);
  $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
  return $ldapobject;
}

print "\nKOLAB BOOTSTRAP\n\n";

# Check for already running services preventing proper operation of kolab_bootstrap and Kolab
checkPort("webserver",80);    # http
checkPort("webserver",443);   # https
checkPort("imap server",143); # imap
checkPort("imap server",220); # 
checkPort("imap server",585);
checkPort("imap server",993);
checkPort("pop3 server",109);
checkPort("pop3 server",110);  # pop3
checkPort("pop3 server",473);
checkPort("pop3 server",995);
checkPort("smtp server",25);   # smtp
checkPort("smtp server",465);
checkPort("ftp server",21);
checkPort("Amavis Virus Scanner Interface",10024);
checkPort("Kolab daemon",9999);
checkPort("OpenLDAP server",636);
checkPort("OpenLDAP server",389);
checkPort("Sieve server",2000);

print ("Excellent all required Ports are available!\n");

system("@sbindir@/slapcat >/dev/null 2>&1");
if ($?==0) {
  print ("\nFound existing configuration\n");
  print "\nBootstrapping Kolab will overwrite old configuration\n";
  my $tmp = getUserInput( "\nContinue", "n", "y", "n" );
  if( (lc $tmp eq 'n') || ($tmp eq '')  ) {
    print "Bootstrapping aborted - not creating new configuration\n";
    exit 0;
  }
  print "Creating backup of old configuration (LDAP, kolab.conf and certificates\n";
  my $epochseconds = timelocal(gmtime);
  my $backupdir="@sysconfdir@/kolab/backup".$epochseconds;
  mkdir($backupdir,0700) || die "cannot mkdir : $!";
  print "creating backup of LDAP repository\n";
  system("cp -pRP "@ldapserver_dir@ .$backupdir."/openldap-data");
  system("rm -f @ldapserver_dir@/*");
  print "creating backup of CA data\n";
  system(mv @sysconfdir@/kolab/ca .$backupdir);
  system(mv @sysconfdir@/kolab/*.pem .$backupdir);
  system("mv $kolab_config $backupdir");
  print "Cleaning up LDAP\n";
  system(rm -f @ldapserver_dir@/*");
} else {
  print "LDAP repository is empty - assuming fresh install\n";
}


# fetch fresh template
copy(@sysconfdir@/kolab/templates/kolab.conf.template, $kolab_config);

my $fd = IO::File->new($kolab_config, "r")
   || die "could not open $kolab_config";
foreach (<$fd>) {
   if (/(.*) : (.*)/) {
      $kolab_config{$1} = $2;
   }
}
undef $fd;
my $fqdnhostname = $kolab_config{'fqdnhostname'} || die "could not read fqdnhostname from $kolab_config";
my $is_master = $kolab_config{'is_master'} || "true";
my $bind_dn = $kolab_config{'bind_dn'} || die "could not read bind_dn from $kolab_config";
my $bind_pw = $kolab_config{'bind_pw'} || die "could not read bind_pw from $kolab_config";
my $bind_pw_hash = $kolab_config{'bind_pw_hash'} || hashPassword( $bind_pw );
my $ldap_uri = $kolab_config{'ldap_uri'} || die "could not read ldap_uri from $kolab_config";
my $base_dn = $kolab_config{'base_dn'} || die "could not read base_dn from $kolab_config";
my $php_dn = $kolab_config{'php_dn'} || die "could not read php_dn from $kolab_config";
my $php_pw = $kolab_config{'php_pw'} || die "could not read php_pw from $kolab_config";
my $calendar_dn = $kolab_config{'calendar_dn'};
my $calendar_pw = $kolab_config{'calendar_pw'};
my @kolabhosts;

if (!$bind_dn || !$bind_pw || !$ldap_uri || !$base_dn) {
   print "Please check $kolab_config (seems to be incomplete)\n";
   die "and run kolab_bootstrap afterwards, manually";
}
my $fqdn;
if( $fqdnhostname =~ /\@\@\@/ ) {
  $fqdn = myhostname;
} else {
  $fqdn = $fqdnhostname;
}
chomp($fqdn);

$fqdn = getUserInput("Please enter Hostname including Domain Name (e.g. thishost.domain.tld)", $fqdn);
print "Proceeding with Hostname $fqdn\n";

my $tmp;
if( $is_master eq "false" ) {
  $tmp = "2";
} else {
  $tmp = "1";
}

my $tmp2 = getUserInput( "Do you want to set up (1) a master Kolab server or (2) a slave",
			 $tmp, "1", "2");
if ( $tmp2 eq "2" ) {
  $is_master = "false";
  print "Proceeding with slave server setup\n\n";
} else {
  $is_master = "true";
  print "Proceeding with master server setup\n\n";
}

if ( $is_master eq "true" ) {
  ##### Master server setup
  getopt('f');

  (my $dummy, my $domain) = split(/\./, $fqdn, 2);
  if (!$domain) {
    $domain = $fqdn;
  }

  $domain = getUserInput("Please enter your Maildomain - if you do not know your mail domain use the fqdn from above", $domain);
  print "proceeding with Maildomain $domain\n";
  print "Kolab primary email addresses will be of the type user\@$domain \n";
  

  if ( $opt_f || $base_dn =~ /\@\@\@/ || $bind_dn =~ /\@\@\@/ || $bind_pw =~ /\@\@\@/ ) {
    print "Generating default configuration:\n";
    if ($base_dn =~ /\@\@\@/) {
      $base_dn = "";
      foreach my $dc ((split(/\./,$domain))) {
        $base_dn .= "dc=$dc,";
      }
      chop $base_dn;
      print " base_dn : $base_dn\n";
    }
    if ($bind_dn =~ /\@\@\@/) {
      $bind_dn =~ s/\@\@\@kolab_basedn\@\@\@/$base_dn/g;
      print " bind_dn : $bind_dn\n";
    }
    if ($bind_pw =~ /\@\@\@/) {
      $bind_pw = `@bindir@/openssl rand -base64 12`;
      chomp $bind_pw;
      $bind_pw = getUserInput("Please choose a manager password", $bind_pw);
      print " bind_pw : $bind_pw\n";
      $bind_pw_hash = hashPassword($bind_pw);
    }

    # Generate passwords
    if ($php_dn =~ /\@\@\@/) {
      $php_dn =~ s/\@\@\@kolab_basedn\@\@\@/$base_dn/g;
    }
    if ($php_pw =~ /\@\@\@/) {
      $php_pw = `@bindir@/openssl rand -base64 30`;
      chomp $php_pw;
    }
    if ($calendar_dn =~ /\@\@\@/) {
      $calendar_dn =~ s/\@\@\@kolab_basedn\@\@\@/$base_dn/g;
      chomp $calendar_dn;
    }
    if ($calendar_pw =~ /\@\@\@/) {
      $calendar_pw = `@bindir@/openssl rand -base64 30`;
      chomp $calendar_pw;
    }

    $fd = IO::File->new($kolab_config, "w+") || die "could not open $kolab_config";
    print $fd "fqdnhostname : $fqdn\n";
    print $fd "is_master : $is_master\n";
    print $fd "base_dn : $base_dn\n";
    print $fd "bind_dn : $bind_dn\n";
    print $fd "bind_pw : $bind_pw\n";
    print $fd "bind_pw_hash : $bind_pw_hash\n";
    print $fd "ldap_uri : $ldap_uri\n";
    print $fd "ldap_master_uri : $ldap_uri\n";
    print $fd "php_dn : $php_dn\n";
    print $fd "php_pw : $php_pw\n";
    print $fd "calendar_dn : $calendar_dn\n";
    print $fd "calendar_pw : $calendar_pw\n";
    undef $fd;
    print "done modifying $kolab_config\n\n";
    chmod 0600, $kolab_config;
    kolab_chown "@kolab_musr@","@kolab_mgrp@",$kolab_config;
    print "IMPORTANT NOTE:\n";
    print "use login=manager and passwd=$bind_pw when you log into the webinterface!\n\n";
  }

  # Set up slapd to replicate to slave server's kolabds
  @kolabhosts = ( $fqdn );
  while(1) {
    my $tmp = getUserInput("Enter fully qualified hostname of slave kolab server e.g. thishost.domain.tld [empty when done]");
    if( $tmp ) {
      push @kolabhosts, $tmp;
      #$cfg .= "replica host=$tmp\n";
      #$cfg .= "  binddn=\"cn=replicator\"\n";
      #$cfg .= "  bindmethod=simple credentials=secret\n\n";
    } else {
      last;
    }
  };

  my $confname = "@emailserver_sasl_conffile@";
  copy("@sysconfdir@/kolab/templates/smtpd.conf.template", $confname) || die "could not write to $confname";

  getopts('b');

  if ($opt_b) {
    print "prepare LDAP database...\n";
    if ($ldap_uri =~ /127\.0\.0\.1/ || $ldap_uri =~ /localhost/) {
#      This cannot happen anymore
#      print "stop running slapd (if any)\n";
#      system("@bindir@/openpkg rc openldap stop");
#      sleep 5;

      # Make sure that no rogue daemons are running
      tryConnect( '127.0.0.1', 389 ) && die "A process is already listening to port 389 (ldap)\n"
        ."Please stop any running ldap server and bootstrap again\n";
      tryConnect( '127.0.0.1', 9999 ) && die "A process is already listening to port 9999 (kolabd)\n"
        ."Please stop any running kolabd and bootstrap again\n";
      if( `ps aux|grep slurpd|grep -v grep` ) {
        print "Error: Detected running slurpd processes.\n";
        print "Please make sure the OpenLDAP server is stopped properly!\n";
        exit 1;
      }

      # Creating slapd.conf from template
      my $tmpl = IO::File->new("@sysconfdir@/kolab/templates/slapd.conf.template", "r") || die "could not read @sysconfdir@/kolab/templates/slapd.conf.template";
      my $slpd = IO::File->new("@ldapserver_confdir@/slapd.conf","w+") || die "could not write to @ldapserver_confdir@/slapd.conf";
      chmod (0640,"@ldapserver_confdir@/slapd.conf");
      while (<$tmpl>) {
        if (/^KOLAB_META_START$/) {
           my $found_end;
           while (!$found_end) {
               $_ = <$tmpl>;
               $found_end = /^KOLAB_META_END$/;
           }
			  $_ = <$tmpl>;
		 }
        s/\@\@\@base_dn\@\@\@/$base_dn/g;
        s/\@\@\@bind_dn\@\@\@/$bind_dn/g;
        s/\@\@\@bind_pw_hash\@\@\@/$bind_pw/g;
        s/TLSCertificate/\#TLSCertificate/g;
        print $slpd $_;
      }
      undef $slpd;
      undef $tmpl;
      
		my $tmplname = "@sysconfdir@/kolab/templates/slapd.replicas.template";
      $confname = "@ldapserver_confdir@/slapd.replicas";

      $tmpl = IO::File->new($tmplname, "r") || die "could not read $tmplname";
      $slpd = IO::File->new($confname,"w+") || die "could not write to $confname";
      chmod (0640,$confname);
      while (<$tmpl>) {
        if (/^KOLAB_META_START$/) {
           my $found_end;
           while (!$found_end) {
               $_ = <$tmpl>;
               $found_end = /^KOLAB_META_END$/;
           }
           $_ = <$tmpl>;
        }
         print $slpd $_;
      }
      undef $slpd;
		undef $tmpl;
		
		$tmplname = "@sysconfdir@/kolab/templates/slapd.access.template";
		
      $confname = "@ldapserver_confdir@/slapd.access";

      $tmpl = IO::File->new($tmplname, "r") || die "could not read $tmplname";
      $slpd = IO::File->new($confname,"w+") || die "could not write to $confname";
      chmod (0640,$confname);
      while (<$tmpl>) {
        if (/^KOLAB_META_START$/) {
           my $found_end;
           while (!$found_end) {
               $_ = <$tmpl>;
               $found_end = /^KOLAB_META_END$/;
           }
           $_ = <$tmpl>;
        }
         print $slpd $_;
       }
       undef $slpd;
       undef $tmpl;
		
      # now we must startup slapd
      print "temporarily starting slapd\n";
      $ldap_uri = "ldap://127.0.0.1:389/";
      (system("@libexecdir@/openldap/slapd -h ldap://127.0.0.1:389/ -f @ldapserver_confdir@/slapd.conf") == 0 ) || die( "Could not start temporary slapd" );
      print ("Waiting for OpenLDAP to start\n");
      sleep 10;

    }

    my $ldapuri = URI->new($ldap_uri) || die "error: could not parse given uri";
    my $ldap = Net::LDAP->new($ldap_uri, verify => 'none' ) || die "could not connect ldap server $ldap_uri";
    if ($ldap) {
      $ldap->bind($bind_dn, password=> $bind_pw) || die "could not bind to ldap server $ldap_uri";
      my $mesg = $ldap->search(base=> "$base_dn", scope=> 'exact', filter=> "(objectclass=*)");
      if ($mesg && $mesg->count != 1) {
        print "no $base_dn object found, creating one\n";
        my $dccomp = (split(/\./,$domain))[0];
        chomp $dccomp;
        $mesg = $ldap->add( $base_dn, attr=> [dc=> $dccomp, 'objectclass'=> ['top', 'domain'] ]);
      }
      $mesg && $mesg->code && warn "failed to write basedn entry : ", $mesg->error;
      my $ldapobject = newOrExistingLDAPEntry( $ldap, "k=kolab,$base_dn" );

      # create kolab config object
      my $mynetworkinterfaces = "127.0.0.0/8";
      print "mynetworkinterfaces: ".$mynetworkinterfaces."\n";

      $ldapobject->replace(
        'k' => 'kolab',
        'kolabhost' => \@kolabhosts,
        'postfix-mydomain' => $domain,
        #'postfix-relaydomains' => "",
        'postfix-mydestination' => "$domain",
        'postfix-mynetworks' => $mynetworkinterfaces,
        #'postfix-relayhost' => "",
        #'postfix-transport' => "",
        'postfix-enable-virus-scan' => "TRUE",
        'cyrus-autocreatequota' => 100000,
        'cyrus-quotawarn' => 80,
        'cyrus-admins' => "manager",
        'cyrus-imap' => "TRUE",
        'cyrus-pop3' => "FALSE",
        'cyrus-imaps' => "TRUE",
        'cyrus-pop3s' => "TRUE",
        'cyrus-sieve' => "TRUE",
        'apache-http' => "FALSE",
        'apache-allow-unauthenticated-fb' => "FALSE",
        'proftpd-ftp' => "FALSE",
        #'proftpd-defaultquota' => 100000,
        #'proftpd-userPassword' => "freebusy",
        'uid' => "freebusy",
        'userPassword' => "freebusy",
        'objectclass' => ['top', 'kolab' ] );
      # Get rid of fqdnhostname, it will cause pain and suffering...
      #$ldapobject->delete( 'fqdnhostname' );
      $ldapobject->dn("k=kolab,$base_dn");
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create internal user topnode
      $ldapobject = newOrExistingLDAPEntry( $ldap, "cn=internal,$base_dn" );
      $ldapobject->replace('cn' => 'internal', 'objectclass' => ['top','kolabnamedobject']);
      $ldapobject->dn("cn=internal,$base_dn");
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create domain groups topnode
      $ldapobject = newOrExistingLDAPEntry( $ldap, "cn=domains,cn=internal,$base_dn" );
      $ldapobject->replace('cn' => 'domains', 'objectclass' => ['top','kolabnamedobject']);
      $ldapobject->dn("cn=domains,cn=internal,$base_dn");
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create external user topnode
      $ldapobject = newOrExistingLDAPEntry( $ldap, "cn=external,$base_dn" );
      $ldapobject->replace('cn' => 'external', 'objectclass' => ['top','kolabnamedobject']);
      $ldapobject->dn("cn=external,$base_dn");
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create groups user topnode
      $ldapobject = newOrExistingLDAPEntry( $ldap, "cn=groups,$base_dn" );
      $ldapobject->replace('cn' => 'groups', 'objectclass' => ['top','kolabnamedobject']);
      $ldapobject->dn("cn=groups,$base_dn");
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create resources user topnode
      $ldapobject = newOrExistingLDAPEntry( $ldap, "cn=resources,$base_dn" );
      $ldapobject->replace('cn' => 'resources', 'objectclass' => ['top','kolabnamedobject']);
      $ldapobject->dn("cn=resources,$base_dn");
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create admin group
      newkolabgroupofnames( $ldap, "cn=internal,$base_dn", 'admin', $bind_dn );

      # create manager user
      $ldapobject = newOrExistingLDAPEntry( $ldap, $bind_dn );
      $ldapobject->replace('cn' => 'manager', 'sn' => 'n/a', 'uid' => 'manager',
                           'userPassword' => $bind_pw_hash, 'objectclass' => ['top','inetorgperson','kolabinetorgperson']);
      $ldapobject->dn($bind_dn);
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create php read-only user
      $ldapobject = newOrExistingLDAPEntry( $ldap, "cn=nobody,cn=internal,$base_dn" );
      $ldapobject->replace('cn' => 'nobody', 'sn' => 'n/a n/a', 'uid' => 'nobody',
                           'userPassword' => hashPassword($php_pw), 
			   'objectclass' => ['top','inetorgperson','kolabinetorgperson']);
      $ldapobject->dn("cn=nobody,cn=internal,$base_dn");
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create calendar user
      $ldapobject = newOrExistingLDAPEntry( $ldap, "cn=calendar,cn=internal,$base_dn" );
      $ldapobject->replace('cn' => 'calendar', 'sn' => 'n/a n/a', 'uid' => 'calendar@'.$domain,
                           'userPassword' => hashPassword($calendar_pw), 
			   'objectclass' => ['top','inetorgperson','kolabinetorgperson']);
      $ldapobject->dn("cn=calendar,cn=internal,$base_dn");
      $mesg = $ldapobject->update($ldap);
      $mesg && $mesg->code && warn "failed to write entry: ", $mesg->error;
      undef $ldapobject;

      # create mainainter group
      newkolabgroupofnames( $ldap, "cn=internal,$base_dn", 'maintainer', $bind_dn );

      # create domain-mainainter group
      newkolabgroupofnames( $ldap, "cn=internal,$base_dn", 'domain-maintainer', $bind_dn );

      $ldap->unbind;
   }

   print "LDAP setup finished\n\n";

   print "Create initial config files for postfix, apache, proftpd, cyrus imap, saslauthd\n";

   my $cfg;
   open(FH, "<@sysconfdir@/rc.conf") || die;
   $cfg .= $_ while (<FH>);
   close(FH);

   $cfg =~ s/\n((openldap_url|sasl_authmech)\S*=[^\n]*)/#$1\n/sg;
   $cfg .= "openldap_url=\"ldap:// ldaps://\"\nsasl_authmech=\"ldap\"\n";

   open(FH, ">@sysconfdir@/rc.conf") || die;
   print FH $cfg;
   close(FH);
   undef $cfg;

   #print " running @sysconfdir@/kolab/kolab -v -o -l$ldap_uri\n";
   print "running @sbindir@/kolabconf -n\n";

   #system("@sysconfdir@/kolab/kolab -v -o -l$ldap_uri");
   system("@sbindir@/kolabconf -n");

   if ($ldap_uri =~ /127\.0\.0\.1/ || $ldap_uri =~ /localhost/) {
      print "\nkill temporary slapd\n\n";
      system("@sysconfdir@/rc openldap stop");
      sleep 5;
      system("killall -9 slapd >/dev/null 2>&1");
   }
  }

  # Create key-pair for resource password encryption 
  # if they dont exist already
  my $pubreskey = "@sysconfdir@/kolab/res_pub.pem";
  my $privreskey = "@sysconfdir@/kolab/res_priv.pem";
  if( ! -e $pubreskey || ! -e $privreskey ) {
    my $oldmask = umask 0077;
    #print "Creating DSA keypair for resource password encryption\n";
    #system("@bindir@/openssl dsaparam 1024 -out dsa-params");
    #system("@bindir@/openssl gendsa -out $privreskey dsa-params");
    #system("@bindir@/openssl dsa -in $privreskey -pubout -out $pubreskey");
    print "Creating RSA keypair for resource password encryption\n";
    kolab_system("@bindir@/openssl genrsa -out $privreskey 1024");
    kolab_system("@bindir@/openssl rsa -in $privreskey -pubout -out $pubreskey");
    kolab_system("chown @kolab_musr@:@kolab_grp@ $pubreskey $privreskey");
    chmod 0660, $privreskey, $pubreskey;
    #unlink( "dsa-params" );
    umask $oldmask;
  }

  print <<'EOS';
Kolab can create and manage a certificate authority that can be
used to create SSL certificates for use within the Kolab environment.
You can choose to skip this section if you already have certificates
for the Kolab server.
EOS

  my $tmp = getUserInput( "Do you want to create CA and certificates", "y", "y", "n");
  if( lc $tmp eq 'n' ) {
    print <<'EOS';
Skipping certificate creation. Please copy your certificate to
@sysconfdir@/kolab/cert.pem and private key to
@sysconfdir@/kolab/key.pem when the bootstrap script is finished.

EOS
  } else {
    print <<'EOS';
Now we need to create a cerificate authority (CA) for Kolab and a server
certificate. You will be prompted for a passphrase for the CA.
################################################################################
EOS
    kolab_system("@sysconfdir@/kolab/kolab_ca.sh -newca $fqdn");
    kolab_system("@sysconfdir@/kolab/kolab_ca.sh -newkey $fqdn @sysconfdir@/kolab/key.pem");
    kolab_system("@sysconfdir@/kolab/kolab_ca.sh -newreq $fqdn @sysconfdir@/kolab/key.pem @sysconfdir@/kolab/newreq.pem ");
    kolab_system("@sysconfdir@/kolab/kolab_ca.sh -sign @sysconfdir@/kolab/newreq.pem @sysconfdir@/kolab/cert.pem");
    kolab_system("chgrp @kolab_rusr@ @sysconfdir@/kolab/key.pem;");
    kolab_system("chmod 0640 @sysconfdir@/kolab/key.pem;");
    kolab_system("chgrp @kolab_rusr@ @sysconfdir@/kolab/cert.pem;");
    kolab_system("chmod 0640 @sysconfdir@/kolab/cert.pem;");
    print <<'EOS';
################################################################################
CA and certificate creation complete.

You can install @sysconfdir@/kolab/ca/cacert.pem on your clients to allow them
to verify the validity of your server certificates.

EOS
  }
} else {
  ##### Slave server setup

  print "stop running slapd (if any)\n";
  kolab_system("@bindir@/openpkg rc openldap stop");
  sleep 1;
  kolab_system("@bindir@/openpkg rc openldap stop");
  sleep 1;

  # Make sure that no rogue demons are running
  tryConnect( '127.0.0.1', 389 ) && die "A process is already listening to port 389 (ldap)\n"
    ."Please stop any running ldap server and bootstrap again\n";
  tryConnect( '127.0.0.1', 9999 ) && die "A process is already listening to port 9999 (kolabd)\n"
    ."Please stop any running kolabd and bootstrap again\n";
  if( `ps aux|grep slurpd|grep -v grep` ) {
    print "WARNING: Detected running slurpd processes.\n";
    print " Please make sure the OpenLDAP server is stopped properly!\n";
  }

  # For now we just connect to the remote slapd
 SLAVESTART:
  print "Now some information about the master LDAP server is required:\n\n";
  do { 
      $ldap_uri = getUserInput("URI of master LDAP server (for example ldaps://host.example.com)", 
			       $ldap_uri);
  } until $ldap_uri;
  my $ldapuri = URI->new($ldap_uri) || warn "error: could not parse given uri";
  if( $ldapuri ) {
    $base_dn = join( ',', map { "dc=$_" } split /\./, $ldapuri->host() );
  }
  $base_dn = getUserInput("Base DN of server", $base_dn);
  print "proceeding with base DN $base_dn\n";

  $bind_dn = "cn=manager,cn=internal,$base_dn";
  $bind_pw = getUserInput("Manager password");
  $bind_pw_hash = hashPassword($bind_pw);

  my $confname = "@emailserver_sasl_conffile@";
  copy("@sysconfdir@/kolab/templates/smtpd.conf.template", $confname) || die "could not write to $confname";

  print "Checking server info...\n";
  my $ldap = Net::LDAP->new($ldap_uri, verify => 'none', onerror => 'undef' );
  if (!defined($ldap)) {
    print "Could not connect to ldap server at $ldap_uri, please check your input\n";
    goto SLAVESTART;
  }
  $ldap->bind($bind_dn, password=> $bind_pw) || warn "could not bind to ldap";
  my $mesg = $ldap->search(base=> "$base_dn", scope=> 'exact', filter=> "(objectclass=*)");
  if ($mesg && $mesg->count != 1) {
    print "No $base_dn object found, please check your input\n";
    goto SLAVESTART;
  }
  $php_dn = "cn=nobody,cn=internal,$base_dn";
  $mesg = $ldap->search(base=> $php_dn, scope=> 'exact', filter=> "(objectclass=*)");
  if ($mesg && $mesg->count != 1) {
    print "Nobody object not found, please check your input\n";
    goto SLAVESTART;
  }
  #my $entry = $mesg->entry(0);
  #$php_pw = $entry->get_value( 'userPassword' );

  $calendar_dn = "cn=calendar,cn=internal,$base_dn";
  $mesg = $ldap->search(base=> $php_dn, scope=> 'exact', filter=> "(objectclass=*)");
  if ($mesg && $mesg->count != 1) {
    print "Calendar object not found, please check your input\n";
    goto SLAVESTART;
  }
  #$entry = $mesg->entry(0);
  #$calendar_pw = $entry->get_value( 'userPassword' );

  $mesg = $ldap->search(base=> "k=kolab,$base_dn", scope=> 'exact',
			filter=> "(objectClass=*)");
  if ($mesg && $mesg->count != 1) {
    print "No Kolab object found, please check your input\n";
    goto SLAVESTART;
  }
  my $kolabhosts = $mesg->entry(0)->get_value( 'kolabhost', asref => 1 );
  foreach(@$kolabhosts) {
    if( lc($_) eq lc($fqdn) ) {
	goto SLAVEOK;
    }
  }
  print "$fqdn is not listed on the master, please correct that and try again\n";
  goto SLAVESTART;
 SLAVEOK:

  my $master_host = $ldapuri->host();

  print "Reading nobody and calendar passwords from master, please type in master's root-password when asked\n";
  open( CONF, "ssh -C $master_host 'cat @sysconfdir@/kolab/kolab.conf'|");
  my $conf;
  $conf .= $_ while(<CONF>);
  close(CONF);
  $conf =~ /php_pw : (.*)/;
  $php_pw = $1;
  $conf =~ /calendar_pw : (.*)/;
  $calendar_pw = $1;

  (print "Error reading nobody password" && goto SLAVESTART) unless( $php_pw );
  (print "Error reading calendar password" && goto SLAVESTART) unless( $calendar_pw );

  $fd = IO::File->new($kolab_config, "w+") || die "could not open $kolab_config";
  print $fd "fqdnhostname : $fqdn\n";
  print $fd "is_master : $is_master\n";
  print $fd "base_dn : $base_dn\n";
  print $fd "bind_dn : $bind_dn\n";
  print $fd "bind_pw : $bind_pw\n";
  print $fd "bind_pw_hash : $bind_pw_hash\n";
  print $fd "ldap_uri : $ldap_uri\n";
  print $fd "ldap_master_uri : $ldap_uri\n";
  print $fd "php_dn : $php_dn\n";
  print $fd "php_pw : $php_pw\n";
  print $fd "calendar_dn : $calendar_dn\n";
  print $fd "calendar_pw : $calendar_pw\n";
  undef $fd;
  print "done modifying $kolab_config\n\n";
  chmod 0600, $kolab_config;
  kolab_chown "@kolab_musr@","@kolab_mgrp@",$kolab_config;

  print << 'EOS';
Now the master server needs to be stopped briefly while the contents of the LDAP database
is copied over to this slave. Please make sure that this slave is entered into the list 
of kolabhosts on the master before proceeding.
EOS
  kolab_system("ssh -CA $master_host @bindir@/openpkg rc openldap stop");
  kolab_system("ssh -CA $master_host @libdir@/openpkg/tar -C @ldapserver_confdir@ -pcf - openldap-data | @libdir@/openpkg/tar -C @ldapserver_confdir@ -pxf -");
  kolab_system("ssh -CA $master_host @bindir@/openpkg rc openldap start");

  print "Updating configuration, please ignore any initial errors from kolabconf\n\n";
  my $cfg;
  open(FH, "<@sysconfdir@/rc.conf") || die;
  $cfg .= $_ while (<FH>);
  close(FH);
  
  $cfg =~ s/\n((openldap_url|sasl_authmech|openldap_enable)\S*=[^\n]*)/#$1\n/sg;
  # $cfg .= "openldap_enable=\"no\"\nopenldap_url=\"\"\nsasl_authmech=\"ldap\"\n";
  $cfg .= "\nopenldap_url=\"ldap:// ldaps://\"\nsasl_authmech=\"ldap\"\n";
  
  open(FH, ">@sysconfdir@/rc.conf") || die;
  print FH $cfg;
  close(FH);
  undef $cfg;
  
  print <<'EOS';
If you chose to create a CA on the master server, you will now need to create
a certificate request and copy it to the master to get it signed. If you already
have a certificate for this server, you can choose to skip this section.
EOS
  my $tmp = getUserInput( "Do you want to create a certificate request and sign it", 
			  "y", "y", "n");
  if( lc $tmp eq 'n' ) {
    print <<'EOS';
Skipping certificate creation. Please copy your certificate to
@sysconfdir@/kolab/cert.pem and private key to
@sysconfdir@/kolab/key.pem when the bootstrap script is finished.

EOS
  } else {
    
    print <<'EOS';
Now we need to create a cerificate request for this slave
and then ssh to the master server to have the request signed.
You will be asked multiple times for the root password of the
master server and the passphrase for the CA key on the master.
################################################################################
EOS

    # Create cert req
    kolab_system("@sysconfdir@/kolab/kolab_ca.sh -newkey $fqdn @sysconfdir@/kolab/key.pem");
    kolab_system("@sysconfdir@/kolab/kolab_ca.sh -newreq $fqdn @sysconfdir@/kolab/key.pem @sysconfdir@/kolab/newreq.pem ");
    # Log into master and sign cert request
    kolab_system("scp @sysconfdir@/kolab/newreq.pem $master_host:@sysconfdir@/kolab/$fqdn-req.pem");
    kolab_system("ssh -CA $master_host \"@sysconfdir@/kolab/kolab_ca.sh -sign @sysconfdir@/kolab/$fqdn-req.pem @sysconfdir@/kolab/$fqdn.pem;\"");
    kolab_system("scp $master_host:@sysconfdir@/kolab/$fqdn.pem @sysconfdir@/kolab/cert.pem");
    kolab_system("ssh -CA $master_host \"rm @sysconfdir@/kolab/$fqdn.pem @sysconfdir@/kolab/$fqdn-req.pem\"");
    die("Creation of @sysconfdir@/kolab/cert.pem failed") unless -f "@sysconfdir@/kolab/cert.pem";
    kolab_system("chgrp @kolab_rgrp@ @sysconfdir@/kolab/key.pem;");
    kolab_system("chmod 0640 @sysconfdir@/kolab/key.pem;");
    kolab_system("chgrp @kolab_rgrp@ @sysconfdir@/kolab/cert.pem;");
    kolab_system("chmod 0640 @sysconfdir@/kolab/cert.pem;");
    
    print <<'EOS';
################################################################################
Certificate creation done!

EOS
  }

  print <<'EOS';
To be able to encrypt and decrypt passwords for group and resource accounts
we need to copy the RSA keypair used for that purpose from the master server.
EOS
  my $privreskey = "@sysconfdir@/kolab/res_priv.pem";
  my $pubreskey  = "@sysconfdir@/kolab/res_pub.pem";
  kolab_system("scp $master_host:$privreskey "
	       ."$master_host:$pubreskey "
	       ."@sysconfdir@/kolab/");
  kolab_system("chown @kolab_musr@:@kolab_grp@ $pubreskey $privreskey");
  chmod 0660, $privreskey, $pubreskey;
  kolab_system("@sbindir@/kolabconf -n");

  $fd = IO::File->new($kolab_config, "w+") || die "could not open $kolab_config";
  print $fd "fqdnhostname : $fqdn\n";
  print $fd "is_master : $is_master\n";
  print $fd "base_dn : $base_dn\n";
  print $fd "bind_dn : $bind_dn\n";
  print $fd "bind_pw : $bind_pw\n";
  print $fd "ldap_uri : ldap://127.0.0.1\n";
  print $fd "ldap_master_uri : $ldap_uri\n";
  print $fd "php_dn : $php_dn\n";
  print $fd "php_pw : $php_pw\n";
  print $fd "calendar_dn : $calendar_dn\n";
  print $fd "calendar_pw : $calendar_pw\n";
  undef $fd;
  print "done modifying $kolab_config\n\n";
  chmod 0600, $kolab_config;
}

#system("@sysconfdir@/kolab/kolab_sslcert.sh $fqdn");
print "kolab is now ready to run!\n";
print "please run '@bindir@/openpkg rc all start'\n";
print ("Use login=manager and passwd=$bind_pw when you log into\n");
print ("the webinterface https://$fqdn/admin !\n");

--- NEW FILE: kolab_ca.sh.in ---
#!@bash_exec@
##
##  Copyright (c) 2004  Klaraelvdalens Datakonsult AB
##   Written by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
##
## CA management script that is heavily inspired by Tim Hudson's
## CA.sh script from the openssl distribution

PREFIX=@prefix@

DAYS="-days 3650"
REQ="$PREFIX/bin/openssl req"
CA="$PREFIX/bin/openssl ca"
VERIFY="$PREFIX/bin/openssl verify"
X509="$PREFIX/bin/openssl x509"
RSA="$PREFIX/bin/openssl rsa"
GENRSA="$PREFIX/bin/openssl genrsa"

CATOP=@sysconfdir@/kolab/ca
CAKEY=cakey.pem
CACERT=cacert.pem

# Make sure not to create world readable files
umask 0077

cd @sysconfdir@/kolab

# Config
function createconf() {
local DNAME=$1
echo "Using dn $hostname"
#if [ ! -d "@sysconfdir@/kolab/ca" ]; then
#    mkdir @sysconfdir@/kolab/ca
#fi
export OPENSSL_CONF=@sysconfdir@/kolab/kolab-ssl.cnf
cat > ${OPENSSL_CONF} <<EOF
[ req ]
distinguished_name = req_distinguished_name
default_bits = 1024
prompt = no
x509_extensions = v3_req
attributes = req_attributes

string_mask = nombstr

[ req_attributes ]

[ req_distinguished_name ]
#C = 
#ST = 
#L = 
#O = 
#OU = 
#CN = 
#emailAddress = 
$DNAME

[ v3_req ]
basicConstraints = CA:TRUE

[ ca ]
default_ca      = CA_kolab

[ CA_kolab ]
dir = $CATOP
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          = \$dir/serial           # The current serial number
#crlnumber      = \$dir/crlnumber        # the current crl number
                                        # must be commented out to leave a V1 CRL
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.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions        = crl_ext

default_days    = 3650                  # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md      = md5                   # which md to use.
preserve        = no                    # keep passed DN ordering

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
commonName              = supplied

[ 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

EOF
}

function readinput() {
    local p=$1
    local d=$2
    read -ep "$p [$d]: " value
    if [ -z "$value" ]; then
	    value="$d"
    fi
}

appname=$0
while [ $# -gt 0 ]; do
case $1 in
-h|-help|--help)
    echo "Usage: $appname {-newca hostname [organization organizational-unit]|-newreq hostname [keyfile] [certfile]|-sign [filename]|-verify [filename]|-help}"
    ;;
-newca)
    if [ ! -f ${CATOP}/serial ]; then
        # create the directory hierarchy
        mkdir ${CATOP}
        mkdir ${CATOP}/certs
        mkdir ${CATOP}/crl
        mkdir ${CATOP}/newcerts
        mkdir ${CATOP}/private
        echo "01" > ${CATOP}/serial
        touch ${CATOP}/index.txt
    fi
    if [ ! -f ${CATOP}/private/$CAKEY ]; then
	cn=$2
	shift
	if [ -n "$2" ]; then
	    o=$2
	    shift
	else
	    readinput "Enter organization name" "Kolab"
	    o=$value
	fi
	if [ -n "$2" ]; then
	    ou=$2
	    shift
	else
	    readinput "Enter organizational unit" "Test-CA"
	    ou=$value
	fi
	shift
	echo "Using subject O=$o,OU=$ou,CN=$cn";
	createconf "O=$o
OU=$ou
CN=$cn"

        echo "CA certificate filename (or enter to create)"
        read FILE

        # ask user for existing CA certificate
        if [ "$FILE" ]; then
            cp $FILE ${CATOP}/private/$CAKEY
            RET=$?
        else
            echo "Making CA certificate ..."
            $REQ -new -x509 -keyout ${CATOP}/private/$CAKEY \
                           -out ${CATOP}/$CACERT $DAYS
            RET=$?
        fi
    fi
    ;;
-newkey)
    # create a new priv. key
    createconf "CN=$2"
    keyfile=key.pem
    if [ -n "$3" ]; then
	keyfile=$3
    fi
    shift 2
    echo "secret"|$GENRSA -des3 -passout fd:0 -out .tmp.pass.key 1024
    echo "secret"|$RSA -passin fd:0 -in .tmp.pass.key -out $keyfile
    rm .tmp.pass.key
    ;;
-newreq)
    # create a certificate request
    createconf "CN=$2"
    reqfile=newreq.pem
    if [ -n "$3" ]; then
	keyfile=$3
    fi
    if [ -n "$4" ]; then
	reqfile=$4
    fi
    shift 3
    $REQ -new -nodes -key ${keyfile} -out ${reqfile} $DAYS
    RET=$?
    echo "Request is in $reqfile and private key is in $keyfile"
    ;;
-sign|-signreq)
    createconf
    infile=newreq.pem
    outfile=newcert.pem
    if [ -n "$2" ]; then
	infile=$2
    fi
    if [ -n "$3" ]; then
	outfile=$3
    fi
    shift 2
    $CA -policy policy_anything -out ${outfile} -infiles ${infile}
    RET=$?
    #cat ${outfile}
    echo "Signed certificate is in ${outfile}"
    ;;
-verify)
    createconf
    shift
    if [ -z "$1" ]; then
            $VERIFY -CAfile $CATOP/$CACERT newcert.pem	    
            RET=$?
    else
        for j
        do
            $VERIFY -CAfile $CATOP/$CACERT $j
            if [ $? != 0 ]; then
                    RET=$?
            fi
        done
    fi
    exit 0
    ;;
*)
    echo "Unknown arg $i";
    exit 1
    ;;
esac
shift
done

cd -

exit $RET


--- NEW FILE: kolab_smtpdpolicy.in ---
#!@perl_exec@

##
##  Copyright (c) 2004  Klaraelvdalens Datakonsult AB
##
##    Writen by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
##
##  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; either version 2, or
##  (at your option) any later version.
##
##  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 can view the  GNU General Public License, online, at the GNU
##  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
##

use Fcntl;
use Sys::Syslog qw(:DEFAULT setlogsock);
use URI;
use Net::LDAP qw(LDAP_NO_SUCH_OBJECT);
use Net::LDAP::Entry;
use Net::hostent;
use Socket;

#
# Usage: kolab_smtpd_policy.pl [-v]
#
# kolabdelegated Postfix SMTPD policy server for Kolab. This server implements
# various policies for Kolab:
#
# 1) Only authenticated users can use From addresses <username>@$domain
# 2) Some distribution lists are only available to authenticated users
#
# Logging is sent to syslogd.
#
# How it works: each time a Postfix SMTP server process is started
# it connects to the policy service socket, and Postfix runs one
# instance of this PERL script.  By default, a Postfix SMTP server
# process terminates after 100 seconds of idle time, or after serving
# 100 clients. Thus, the cost of starting this PERL script is smoothed
# out over time.
#
# To run this from /etc/postfix/master.cf:
#
#    policy  unix  -       n       n       -       -       spawn
#      user=kolab-n argv=/usr/bin/perl /usr/libexec/postfix/kolab_smtpd_policy.pl
#
# To use this from Postfix SMTPD, use in /etc/postfix/main.cf:
#
#    smtpd_recipient_restrictions =
#	...
#	reject_unauth_destination
#	check_policy_service unix:private/policy
#	...
#
# NOTE: specify check_policy_service AFTER reject_unauth_destination
# or else your system can become an open relay.
#
# To test this script by hand, execute:
#
#    % perl kolab_smtpd_policy.pl
#
# Each query is a bunch of attributes. Order does not matter, and
# the demo script uses only a few of all the attributes shown below:
#
#    request=smtpd_access_policy
#    protocol_state=RCPT
#    protocol_name=SMTP
#    helo_name=some.domain.tld
#    queue_id=8045F2AB23
#    sender=foo at bar.tld
#    recipient=bar at foo.tld
#    client_address=1.2.3.4
#    client_name=another.domain.tld
#    instance=123.456.7
#    sasl_method=plain
#    sasl_username=you
#    sasl_sender=
#    size=12345
#    [empty line]
#
# The policy server script will answer in the same style, with an
# attribute list followed by a empty line:
#
#    action=dunno
#    [empty line]
#

#
# Syslogging options for verbose mode and for fatal errors.
# NOTE: comment out the $syslog_socktype line if syslogging does not
# work on your system.
#
$syslog_socktype = 'unix'; # inet, unix, stream, console
$syslog_facility="mail";
$syslog_options="pid";
$syslog_priority="info";

$ldap_max_tries = 5;

sub mylog {
  my $prio = shift;
  my $fmt = shift;

  my $text = sprintf( $fmt, @_ );

  #Kolab::log( 'P', $text );
  syslog $prio, $text;
}

sub contains {
  my $needle = lc(shift);
  my $haystack = shift;
  map { return 1 if $needle eq lc($_) } @$haystack;
  return 0;
}

sub ldap_connect {
    my $ldapuri = URI->new($conf_ldapuri) || fatal_exit("error: could not parse given uri");
    $ldap = Net::LDAP->new($conf_ldapuri) || fatal_exit("could not connect ldap server");
    if ($ldap) {
	if( $conf_binddn ) {
	    $ldap->bind( $conf_binddn, password => $conf_bindpw ) || fatal_exit( "could not bind as $conf_binddn" );
	} else {
	    $ldap->bind || fatal_exit("could not bind");
	}
    } else {
	fatal_exit( "Could not contact LDAP server" );
    }
}

#
# SMTPD access policy routine. The result is an action just like
# it would be specified on the right-hand side of a Postfix access
# table.  Request attributes are available via the %attr hash.
#
sub smtpd_access_policy {

  # Get relevant attributes
  my $sender      = $attr{'sender'};
  my $recip       = $attr{'recipient'};
  my $username    = $attr{'sasl_username'};
  my $client_addr = $attr{'client_address'};

  mylog($syslog_priority, "Checking sender=\"$sender\", recipient=\"$recip\", username=\"$username\", domains=".join(',', at conf_domain)." permithosts=".join(',', at conf_permithosts).", conf_allowunauth=$conf_allowunauth") if $verbose;

  #### This should probably be simplifed to
  #### reject sender <anything>@domain.tld if the user is
  #### not authenticated

 CHECKPERMITHOSTS:
  # First check if the sender is a privileged kolabhost
  # Kolab hosts use un-authenticated smtp currently
  if( !$username ) {
      for my $host (@conf_permithosts) {
	  unless ($h = gethost($host)) {
	      mylog($syslog_priority,"No such host $host\n");
	      next;
	  }
	  for my $addr ( @{$h->addr_list} ) {
	      return "DUNNO" if inet_ntoa($addr) eq $client_addr;
	  }
      }
  }

  # Translate uid to mail:
  my $tries = 0;
 LOOKUPUID:
  my $mesg = $ldap->search( base=> $conf_basedn,
			    scope=> 'sub',
			    filter=> "(&(objectClass=kolabinetorgperson)(|(mail=$username)(uid=$username)))");
  if( !$mesg->code && $mesg->count() > 0 ) {
      mylog($syslog_priority, "LDAP search returned ".$mesg->count()." objects") if $verbose;
      my $ldapobject = $mesg->entry(0);
      $username = lc($ldapobject->get_value('mail'));
      mylog($syslog_priority, "Translated username to $username") if $verbose;
  } elsif( $mesg->code && $mesg->code != LDAP_NO_SUCH_OBJECT ) {
      if( $tries++ <= $ldap_max_tries ) {
	  mylog($syslog_priority, "LDAP Connection error during LOOKUPUID: ".$mesg->error.". trying to reconnect" );
	  ldap_connect;
	  goto LOOKUPUID;
      } else {
	  mylog($syslog_priority, "LDAP Connection error during LOOKUPUID: ".$mesg->error.", giving up!" );
	  return "DEFER_IF_PERMIT LDAP Error during LOOKUPUID:: ".$mesg->error;
      }
  }
  # Check for allowed sender
  $tries = 0;
 CHECKSENDER:

  $mesg = $ldap->search( base=> $conf_basedn,
			    scope=> 'sub', 
			    filter=> "(&(objectClass=kolabinetorgperson)(|(mail=$sender)(alias=$sender)))");
  if( !$mesg->code ) {
    mylog($syslog_priority, "LDAP search returned ".$mesg->count()." objects") if $verbose;
    foreach $ldapobject ($mesg->entries) {
      mylog($syslog_priority, "Got object ".$ldapobject->get_value('uid') ) if $verbose;
      mylog($syslog_priority, "Got delegates ".join(", ", @{$ldapobject->get_value('kolabdelegate', asref => 1 )})) if $verbose;
      if( $username && ( lc($username) eq lc($ldapobject->get_value('uid'))  ||
                         lc($username) eq lc($ldapobject->get_value('mail')) ||
	                 contains( $username, $ldapobject->get_value('kolabdelegate', asref => 1 )))  ) {
	# All OK, user is sending as herself or as kolabdelegate
	mylog($syslog_priority, "$username using valid from address $sender") if $verbose;	
	goto CHECKDISTLIST;
      }
    }
  } else {
      # LDAP error?
      if( $mesg->code != LDAP_NO_SUCH_OBJECT && $tries++ <= $ldap_max_tries ) {
	  mylog($syslog_priority, "LDAP Connection error during CHECKSENDER: ".$mesg->error.", trying to reconnect" );
	  ldap_connect;
	  goto CHECKSENDER;
      } else {
	  mylog($syslog_priority, "Query returned error during CHECKSENDER: ".$mesg->error ) if $verbose;	
	  return "DEFER_IF_PERMIT Temporary LDAP error during CHECKSENDER: ".$mesg->error;
      }
  }
  if( $conf_allowunauth && !$username ) {
    # Dont reject mail from other domains
    $sender =~ /(.*)@(.*)/;
    my $domain = $2;
    mylog($syslog_priority, "sender=$sender, domain=$domain") if $verbose;
    if( !contains( $domain, \@conf_domain ) ) {
      # Ok
      mylog($syslog_priority, "sending from other domains OK") if $verbose;
      goto CHECKDISTLIST;
    }
  }
  # UPS, fake sender
  mylog($syslog_priority, "Attempt to fake address $sender") if $verbose;	
  return "REJECT Invalid sender";
  
  # Check for valid access to restricted distribution lists
  $tries = 0;
 CHECKDISTLIST:
  if( !$username or $username eq '' ) {
    $recip =~ /(.*)@(.*)/;
    my $cn = $1;
    my $domain = $2;
    if( contains($domain,\@conf_domain ) ) {
      $mesg = $ldap->search( base=> "cn=internal,".$conf_basedn,
                             scope=> 'one', filter=> "(&(cn=$cn)(objectClass=kolabgroupofnames))");
      if( !$mesg->code && $mesg->count() > 0 ) {
	# Ups, recipient is a restricted list, reject
	mylog( $syslog_priority, "Attempt from $sender to access restricted list $recip" ) if $verbose;	
	return "REJECT Access denied";
      } elsif( $mesg->code && $mesg->code != LDAP_NO_SUCH_OBJECT && $tries++ <= $ldap_max_tries ) {
	  mylog($syslog_priority, "LDAP Connection error during CHECKDISTLIST: ".$mesg->error.", trying to reconnect" );
	  ldap_connect;
	  goto CHECKDISTLIST;
      } elsif( $mesg->code ) {
	mylog( $syslog_priority, "LDAP Error during CHECKDISTLIST: ".$mesg->error ) if $verbose;
	# Just fall through and accept the message in case there was an LDAP problem.
      }
    }
  }

  # The result can be any action that is allowed in a Postfix access(5) map.
  #
  # To label mail, return ``PREPEND'' headername: headertext
  #
  # In case of success, return ``DUNNO'' instead of ``OK'' so that the
  # check_policy_service restriction can be followed by other restrictions.
  #
  # In case of failure, specify ``DEFER_IF_PERMIT optional text...''
  # so that mail can still be blocked by other access restrictions.

  mylog($syslog_priority, "sender $sender, recipient $recip seems ok") if $verbose;

  return "DUNNO";
}

#
# Log an error and abort.
#
sub fatal_exit {
    my($first) = shift(@_);
    mylog("err", "fatal: $first", @_);
    print STDOUT "action=DEFER_IF_PERMIT $first\n\n";
    exit 1;
}

#
# Signal 11 means that we have crashed perl
#
sub sigsegv_handler {
    fatal_exit "Caught signal 11;";
}

$SIG{'SEGV'} = 'sigsegv_handler';

#
# This process runs as a daemon, so it can't log to a terminal. Use
# syslog so that people can actually see our messages.
#
setlogsock $syslog_socktype;
openlog $0, $syslog_options, $syslog_facility;

#
# We don't need getopt() for now.
#
$conf_allowunauth = 0;
while ($option = shift(@ARGV)) {
  if ($option eq "-v") {
    $verbose = 1;
  } elsif ($option eq '-ldap') {
    $conf_ldapuri = shift(@ARGV);
  } elsif ($option eq '-basedn') {
    $conf_basedn = shift(@ARGV);
  } elsif ($option eq '-binddn' ) {
    $conf_binddn = shift(@ARGV);
  } elsif ($option eq '-bindpw' ) {
    $conf_bindpw = shift(@ARGV);
  } elsif ($option eq '-domain') {
    push @conf_domain, shift(@ARGV);
  } elsif ($option eq '-allow-unauth') {
    $conf_allowunauth = 1;
  } elsif ($option eq '-permithosts') {
    for my $h (split /\s*,\s*/, shift(@ARGV)) {
      push @conf_permithosts, $h;
    }
  } else {
    mylog( $syslog_priority, "Invalid option: %s. Usage: %s [-v] -ldap <uri> -basedn <base_dn> [-binddn <bind_dn> -bindpw <bind_pw>] [-domain <domain>] [-permithosts <host,host,...>]",
	   $option, $0);
    exit 1;
  }
}

#
# Unbuffer standard output.
#
select((select(STDOUT), $| = 1)[0]);

if( $verbose ) {
  mylog( $syslog_priority, "ldap=$conf_ldapuri, basedn=$conf_basedn, binddn=$conf_binddn");
}

ldap_connect;

#
# Receive a bunch of attributes, evaluate the policy, send the result.
#
while (<STDIN>) {
    if (/([^=]+)=(.*)\n/) {
	$attr{substr($1, 0, 512)} = substr($2, 0, 512);
    } elsif ($_ eq "\n") {
	if ($verbose) {
	    for (keys %attr) {
		mylog( $syslog_priority, "Attribute: %s=%s", $_, $attr{$_});
	    }
	}
	fatal_exit "unrecognized request type: '%s'", $attr{'request'}
	    unless $attr{'request'} eq "smtpd_access_policy";
	$action = smtpd_access_policy();
	mylog( $syslog_priority, "Action: %s", $action) if $verbose;
	print STDOUT "action=$action\n\n";
	%attr = ();
    } else {
	chop;
	mylog( $syslog_priority, "warning: ignoring garbage: %.100s", $_);
    }
}

--- NEW FILE: kolab_sslcert.sh.in ---
#!/bin/sh

##  Copyright (c) 2003 Martin Konold <martin.konold at erfrakon.de>
##  Copyright (c) 2003 Tassilo Erlewein <tassilo.erlewein at erfrakon.de>
##  This program is Free Software under the GNU General Public License (>=v2).
##  Read the file COPYING that comes with this packages for details.


cd @sysconfdir@/kolab

if [ $1 ];then
  HN=$1
else
  HN=`hostname -f`
fi

echo "[ req ]" > tmp.req.cnf
echo "distinguished_name = req_distinguished_name" >> tmp.req.cnf
echo "default_bits = 1024" >> tmp.req.cnf
echo "prompt = no" >> tmp.req.cnf
echo "x509_extensions = v3_req" >> tmp.req.cnf
echo >> tmp.req.cnf
echo "string_mask = nombstr" >> tmp.req.cnf
echo >> tmp.req.cnf
echo "[ req_distinguished_name ]" >> tmp.req.cnf
echo "CN = $HN" >> tmp.req.cnf
echo >> tmp.req.cnf
echo "[ v3_req ]" >> tmp.req.cnf
echo "basicConstraints = CA:TRUE" >> tmp.req.cnf

echo -n "generate self-signed certificate for hostname $HN... "

    @bindir@/openssl req -new -x509 -outform PEM -keyform PEM -nodes \
                                   -days 3650 -out cert.pem -keyout key.pem \
		                   -config tmp.req.cnf >/dev/null 2>&1
echo "done"

chgrp @restricted_kolab_grp@ key.pem
chmod 0640 key.pem
chgrp @restricted_kolab_grp@ cert.pem
chmod 0640 cert.pem

#rm -f tmp.req.cnf

cd -

echo "New certificate has been installed under @sysconfdir@/kolab/"

--- NEW FILE: kolabcheckperm.in ---
#!@perl_exec@

# (c) 2004 Klaralvdalens Datakonsult AB
#
# Written by Steffen Hansen <steffen at klaralvdalens-datakonsult.se>
#
# This program is Free Software under the GNU General Public License (>=v2).
# Read the file COPYING that comes with this packages for details.

use strict;
use Kolab;
use Kolab::Util;
use Kolab::Conf;

exit( Kolab::Conf::checkPermissions>0?0:-1 );

--- NEW FILE: kolabconf.in ---
#!@perl_exec@

##
##  Copyright (c) 2003  Code Fusion cc
##
##    Written by Stuart Binge  <s.binge at codefusion.co.za>
##    Portions based on work by the following people:
##
##      (c) 2004  Klaraelvdalens Datakonsult AB
##	(c) 2003  Tassilo Erlewein  <tassilo.erlewein at erfrakon.de>
##      (c) 2003  Martin Konold     <martin.konold at erfrakon.de>
##      (c) 2003  Achim Frank       <achim.frank at erfrakon.de>
##
##
##  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; either version 2 of the License, or
##  (at your option) any later version.
##
##  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, write to the Free Software
##  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##

use strict;
use Getopt::Std;
use Sys::Syslog;
use IO::File;
use Kolab;
use Kolab::Util;
use Kolab::Conf;
use Kolab::LDAP;
use vars qw($opt_d $opt_n $opt_h);

openlog('kolabconf', 'cons, pid', 'user');

getopts('dnh');
if ($opt_h) {
  print <<'EOS';
Usage: kolabconf [-d] [-n] [-h]

Option d (debug) to print out the current config.
Option n (noreload) to skip reloading services after changing configuration.
Option h (help) to get this text.
EOS
exit 0;
}
if ($opt_d) {
    foreach my $key (sort keys %Kolab::config) {
		my $value;
		if( ref($Kolab::config{$key}) eq "ARRAY" ) {
			$value = join( ", ", @{$Kolab::config{$key}});
		} else {
			$value = $Kolab::config{$key};
		}
        print "$key : " . $value . "\n";
    }
    exit 0;
}
my $do_reload = 1;
if($opt_n) {
  $do_reload = 0;
}

print 'kolabconf - Kolab Configuration Generator

  Version: @VERSION@

  Copyright (c) 2004  Klaraelvdalens Datakonsult AB
  Copyright (c) 2003  Code Fusion cc
  Copyright (c) 2003  Tassilo Erlewein, Martin Konold, Achim Frank, erfrakon

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
';

if( !$Kolab::reloadOk ) {
  my $msg = "Error loading configuration. Maybe the LDAP server is not running. Please check the system log for errors.";
  print STDERR "$msg\n";
  Kolab::log('KC', $msg);
  exit(-1);
}
Kolab::log('KC', 'Rebuilding templates');
Kolab::Conf::rebuildTemplates;
Kolab::log('KC', 'Reloading kolab components');
if( $do_reload ) {
  Kolab::reload;
}
#if ($pid) {
#    Kolab::log('KC', "Refreshing the kolab daemon (w/ PID $pid)");
#    kill('HUP', $pid);
#} else {
#    Kolab::log('KC', "Unable to determine the PID of the kolab daemon; skipping refresh", KOLAB_WARN);
#}
Kolab::log('KC', 'Finished');

--- NEW FILE: kolabd.in ---
#!@perl_exec@

##
##  Copyright (c) 2004  Klaraelvdalens Datakonsult AB
##  Copyright (c) 2003  Code Fusion cc
##
##    Writen by Stuart Bing?<s.binge at codefusion.co.za>
##    Portions based on work by the following people:
##
##      (c) 2003  Tassilo Erlewein  <tassilo.erlewein at erfrakon.de>
##      (c) 2003  Martin Konold     <martin.konold at erfrakon.de>
##      (c) 2003  Achim Frank       <achim.frank at erfrakon.de>
##
##
##  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; either version 2, or
##  (at your option) any later version.
##
##  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 can view the  GNU General Public License, online, at the GNU
##  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
##

#
#  Module prefixes in the logs:
#    K: kolabd
#    C: Config
#    T: Templates
#    L: LDAP
#    Y: Cyrus
#    B: Backend
#    KC: kolabconf
#    DS: DirServ
#    Anything else: the various backends
#

use strict;
use Sys::Syslog;
use IO::File;
use Kolab;
use Kolab::Util;
use Kolab::DirServ;
use Kolab::LDAP;
use Kolab::LDAP::Backend;
use vars qw(%pids);

openlog('kolabd', 'cons, pid', 'user');

# won't be needed now (i think)
# my $prefix = $Kolab::config{'prefix'};

my $pidfile = IO::File->new("@kolab_pidfile", 'w+')
    || die "Unable to open PID file `@kolab_pidfile@'";
print $pidfile $$;
undef $pidfile;

sub sigInt
{
    Kolab::Util::superLog('Kolab is shutting down');

    Kolab::log('K', 'SIGINT/SIGTERM detected, kill()ing children');

    foreach my $pid (keys %pids) {
        kill('INT', $pid);
        waitpid($pid, 0);
    }

    Kolab::LDAP::shutdown;

    Kolab::log('K', 'Exiting');
    exit(0);
}

sub sigHup
{
    Kolab::log('K', 'Refreshing configuration');
    foreach my $pid (keys %pids) {
        kill('INT', $pid);
        waitpid($pid, 0);
    }
    %pids = ();
    Kolab::reloadConfig;
    Kolab::log('K', 'Synchronising');
    Kolab::LDAP::sync;
    Kolab::log('K', 'Reloading addressbook.peers');
    Kolab::DirServ::reloadPeers;
    Kolab::log('K', 'Finished refresh');
    &run;
}

sub sigDie {
  Kolab::log( 'K', $_[0], KOLAB_ERROR );
}

sub run
{
    my $pid;
    my $finished = 0;
    foreach my $backend (keys %Kolab::LDAP::Backend::backends) {
        Kolab::log('K', "Forking `$backend' listener");
        $pid = fork;
        if (!defined($pid)) {
	    Kolab::log('K', "Unable to fork `$backend' listener", KOLAB_ERROR);
            exit(1);
        }

        if ($pid) {
            $pids{$pid} = 1;
            $finished++;
            next;
        }
        Kolab::LDAP::Backend::run($backend);

        Kolab::log('K', "`$backend' returned");
	# exit with 0 status to avoid killing daemon
	exit(0);
    }

    $SIG{'INT'} = \&sigInt;
    $SIG{'TERM'} = \&sigInt;
    $SIG{'HUP'} = \&sigHup;
    $SIG{__DIE__} = \&sigDie;

    Kolab::log('K', 'Listeners spawned, wait()ing');

    while ($finished > 0) {
        wait;
        if ($?) {
            Kolab::log('K', 'Abnormal child exit status encountered, aborting');
            kill('INT', $$);
        } else {
            Kolab::log('K', 'Child terminated normally');
        }
    }
}

print 'kolabd - Kolab Backend Daemon

  Copyright (c) 2004  Klaraelvdalens Datakonsult AB
  Copyright (c) 2003  Code Fusion cc
  Copyright (c) 2003  Tassilo Erlewein, Martin Konold, Achim Frank

This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
';

Kolab::Util::superLog('Kolab is starting up');

eval {
  Kolab::LDAP::startup;

  Kolab::log('K', 'Loading backends');
  Kolab::LDAP::Backend::load;
  Kolab::LDAP::Backend::load('user');
  Kolab::LDAP::Backend::load('sf');
  Kolab::LDAP::Backend::load('dirservd',1);
  
  Kolab::log('K', 'Performing backend startup');
  &Kolab::LDAP::Backend::startup;
  
  Kolab::log('K', 'Synchronising');
  Kolab::LDAP::sync;
  
  Kolab::log('K', 'Synchronisation complete, starting up daemon');
  run;
}; Kolab::log( 'K', $@, KOLAB_ERROR ) if $@;


--- NEW FILE: kolabd.spec.in ---
##
##  kolabd.spec -- OpenPKG RPM Specification
##  Copyright (c) 2004-2005 Klaraelvdalens Datakonsult AB <http://www.klaralvdalens-datakonsult.se>
##  Copyright (c) 2000-2004 The OpenPKG Project <http://www.openpkg.org/>
##  Copyright (c) 2000-2004 Ralf S. Engelschall <rse at engelschall.com>
##  Copyright (c) 2000-2004 Cable & Wireless <http://www.cw.com/>
##
##  Permission to use, copy, modify, and distribute this software for
##  any purpose with or without fee is hereby granted, provided that
##  the above copyright notice and this permission notice appear in all
##  copies.
##
##  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
##  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
##  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
##  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
##  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
##  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
##  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
##  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
##  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
##  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
##  SUCH DAMAGE.
##

#   package version
%define       V_ei_maj 2.0
%define       V_ei_min 0
%define       V_cf     1.0.4

#   package information
Name:         kolabd
Summary:      Kolab2 Groupware Server Daemon
URL:          http://www.kolab.org/
Vendor:       Erfrakon, Intevation, Code Fusion, Klaraelvdalens Datakonsult AB
Packager:     Klaraelvdalens Datakonsult AB
Distribution: OpenPKG
Class:        PLUS
Group:        Mail
License:      GPL
Version:      @VERSION@
Release:      @spec_build_date@

#   list of sources
Source0:      kolabd-%{version}.tar.gz
#Source1:      rc.kolabd

#   build information
Prefix:       %{l_prefix}
BuildRoot:    %{l_buildroot}
BuildPreReq:  OpenPKG, openpkg >= 2.0.0
PreReq:       OpenPKG, openpkg >= 2.2.0, openldap >= 2.2.23-2.3.0_kolab2, imapd, sasl, apache, proftpd, perl, perl-ldap, perl-mail
PreReq:       sasl >= 2.1.19-2.2.0, sasl::with_ldap = yes, sasl::with_login = yes
PreReq:       proftpd >= 1.2.10-2.2.0, proftpd::with_ldap = yes
PreReq:       gdbm >= 1.8.3-2.2.0, gdbm::with_ndbm = yes
PreReq:       postfix >= 2.1.5-2.2.0_kolab3, postfix::with_ldap = yes, postfix::with_sasl = yes, postfix::with_ssl = yes
PreReq:       imapd >= 2.2.8-2.2.0_kolab, imapd::with_group = yes
PreReq:       apache >= 1.3.31-2.2.0, apache::with_gdbm_ndbm = yes, apache::with_mod_auth_ldap = yes, apache::with_mod_dav = yes, apache::with_mod_php = yes, apache::with_mod_php_gdbm = yes, apache::with_mod_php_gettext = yes, apache::with_mod_php_imap = yes, apache::with_mod_php_openldap = yes, apache::with_mod_php_xml = yes, apache::with_mod_ssl = yes
PreReq:       perl-kolab >= 5.8.7-20050728, perl-db
PreReq:	      amavisd >= 2.3.1-2.4.0
PreReq:	      clamav
AutoReq:      no
AutoReqProv:  no

%option       kolab_version snapshot

%description
    Kolab is the KDE Groupware Server that provides full groupware
    features to either KDE Kolab clients or Microsoft Outlook[tm]
    clients using third party plugins and web clients in the future. 
    In addition it is a robust and flexible general IMAP mail server 
    with LDAP addressbooks.
    Kolab %{V_ei_maj}.%{V_ei_min}

    The Code Fusion fork adds functionality such as integration with
    Active Directory, a more modularised backend, separation of the
    daemon and the configuration generator and more.
    Code Fusion Engine %{V_cf}, shares Admin (see above)

%track
    prog kolab-ei = {
        version   = %{V_ei_maj}.%{V_ei_min}
        url       = ftp://ftp.kdab.net/pub/kolab/server/current/
        regex     = kolabd-(__VER__)\.src\.rpm
    }

%prep
    %setup -q

%build
    ./configure --prefix=%{l_prefix} --enable-dist=kolab
    %{l_make} %{l_mflags}

%install
    rm -rf $RPM_BUILD_ROOT

    #   install package
    %{l_make} %{l_mflags} install \
        DESTDIR=$RPM_BUILD_ROOT

    #   generate file list
    %{l_rpmtool} files -v -ofiles -r$RPM_BUILD_ROOT %{l_files_std} \
	%dir '%defattr(-,%{l_nusr},%{l_ngrp})' %{l_prefix}/var/kolab/httpd_sessions \
        '%config %{l_prefix}/etc/kolab/*.pem' \
        '%config %{l_prefix}/etc/kolab/*.schema' \
        '%config %{l_prefix}/etc/kolab/kolab.conf' \
	'%config %{l_prefix}/etc/kolab/quotawarning.txt' \
	'%config %{l_prefix}/etc/kolab/templates/*.template'

%files -f files

%clean
    rm -rf $RPM_BUILD_ROOT

%post
    %{l_shtool} echo -e "Installing crontab entry"
	# NOTE: OpenPKG's dcron package does not work currently, 
	# so we have to rely on the host system's cron:
    %{l_shtool} echo -e "`crontab -u %{l_musr} -l | grep -v %{l_prefix}/etc/kolab/kolabquotawarn`" \
	'
*/10 * * * * %{l_prefix}/etc/kolab/kolabquotawarn' | crontab - -u %{l_musr}

    echo "For a fresh install please initialize Kolab by running '$RPM_INSTALL_PREFIX/etc/kolab/kolab_bootstrap -b' as user root."
    echo "If you upgraded from a previous version simply refresh Kolab by running run '$RPM_INSTALL_PREFIX/sbin/kolabconf' as user root."
    echo "In every case execute '$RPM_INSTALL_PREFIX/bin/openpkg rc kolabd restart' as user root."

--- NEW FILE: kolabpasswd.in ---
#!@perl_exec@ -w 

# The kolabpasswd script is used for changing the manager password on a Kolab Server.
# In multi-location Kolab setups the script must be run on each individual host 
# seperately.
# After changing the manager password it is highly recommended to restart 
# the Kolab server.
# In the future this utility may be enhanced to allow to change the passwords of 
# normal users and special system accounts.

##  Copyright (c) 2004  Erfrakon
##
##      (c) 2004  Tassilo Erlewein  <tassilo.erlewein at erfrakon.de>
##      (c) 2004  Martin Konold     <martin.konold at erfrakon.de>
##
##  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; either version 2, or
##  (at your option) any later version.
##
##  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 can view the  GNU General Public License, online, at the GNU
##  Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.

use Term::ReadKey;
use IO::File;
use File::Temp;
use Net::LDAP;
use Kolab::Util;

# won't be needed (i think)
# my $kolab_prefix = (getpwnam('kolab'))[7] || die "Error: could not determine the kolab directory prefix (e.g. /kolab)";

# Hash a password
sub hashPassword {
  my $pw = shift;
  my $hashcmd = "@sbindir@/slappasswd -s '".$pw."'";
  (my $hashpw = `$hashcmd`) or die $@;
  chomp($hashpw);
  return $hashpw;
}

# open old kolab master config file
my $kolabconfname = "@sysconfdir@/kolab/kolab.conf";

# read old config data
my %config = readConfig($kolabconfname);
my $kolabconf = IO::File->new(@sysconfdir@/kolab/kolab.conf','r')
                || die "kolabpasswd: Fatal Error: could not open kolab config at $kolabconfname";

my $account = 'manager';
my $account_dn = $config{'bind_dn'};
if( $#ARGV == 0 ) {
    $account = $ARGV[0];
    if( $account ne 'calendar' and $account ne 'nobody' and $account ne 'manager' ) {
	die("$^X can only change the passwod for manager, nobody and calendar");
    }
    $account_dn =~ s/cn=manager/cn=$account/;
}
      
print "Changing password for $account";

# open ldap connection and verify old password
my $ldap = Net::LDAP->new( $config{'ldap_uri'})
         || die "\nkolabpasswd: Fatal Error: could not connect to LDAP Server";

do {
  print "\nOld Password: ";
  ReadMode 'noecho';
  my $old_password = ReadLine 0; chomp $old_password;

  $mesg = $ldap->bind( $account_dn, password => $old_password ) || die "\nkolabpasswd: Failed to bind to LDAP server";
  if( $mesg->code ) { print "\nError: ".$mesg->error.". Please try again\n"; }
} while ( $mesg->code );
   
# read in new password
print "\nNew Password for $account: ";
ReadMode 'noecho';
my $new_password = ReadLine 0; chomp $new_password;

print "\nRe-enter New Password: ";
my $new_password2 = ReadLine 0; chomp $new_password2;
print "\n";
ReadMode 'normal';
($new_password eq $new_password2) || die "Sorry, passwords do not match.\n";

my $bind_pw_hash;

# create temporary config file
my $tmp = new File::Temp( TEMPLATE => 'tempXXXXX', DIR => '@sysconfdir@/kolab', UNLINK => 0, SUFFIX => '.conf')
     || die "Error: could not create temporary file under @sysconfdir@/kolab";
$tmpfilename = $tmp->filename;
$bind_pw_hash = hashPassword($new_password);

# copy and replace old config to temporary file
foreach ($kolabconf->getlines()) {
    if( $account eq 'manager' ) {
	if (/^(bind_pw\s:\s).*$/) {
	    print $tmp $1.$new_password."\n";
	} else {
	    if (/^(bind_pw_hash\s:\s).*$/) {
		print $tmp $1.$bind_pw_hash."\n"; 
	    } else {
		print $tmp $_;
	    }
	}
    } elsif( $account eq 'calendar' ) {
	if (/^(calendar_pw\s:\s).*$/) {
	    print $tmp $1.$new_password."\n";
	} else {
	    print $tmp $_;
	}
    } elsif( $account eq 'nobody' ) {
	if (/^(php_pw\s:\s).*$/) {
	    print $tmp $1.$new_password."\n";
	} else {
	    print $tmp $_;  
	}
    }
}
undef $tmp;
undef $kolabconf;

# open ldap connection and update manager password
$ldap = Net::LDAP->new( $config{'ldap_uri'})
   || die "Error: could not connect LDAP Server";
$ldap->bind( $config{'bind_dn'}, password => $config{'bind_pw'} )
   || die "Error: Failed to bind as manager to LDAP Server";
$ldap->modify($account_dn, replace => {'userPassword' => $bind_pw_hash } )
   || die "Error: could not update LDAP with new manager password";
$ldap->unbind;
undef $ldap;

# move temporary file to kolab master config
rename($tmpfilename,$kolabconfname) || die "Error: could not install new $kolabconfname";
system("chown @ldapserver_usr@:@ldapserver_grp@ $kolabconfname");

print "Password changed successfully, please be patient...\n";

# trigger kolabd to run update
system("@sbindir@/kolabconf > /dev/null 2>&1");
exit 0;

--- NEW FILE: kolabquotawarn.in ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: rc.kolabd.in ---
#!@prefix@/lib/openpkg/bash @sysconfdir@/rc
##
##  rc.kolabd -- Run-Commands
##

%config
    kolabd_enable="$openpkg_rc_def"
    kolabd_log_resmgr_logfile="@resmgr_logfile@"
    kolabd_log_resmgr_owner="@kolab_usr@"
    kolabd_log_resmgr_group="@kolab_grp@"
    kolabd_log_resmgr_prolog="true"
    kolabd_log_resmgr_epilog="true"
    kolabd_log_resmgr_numfiles="10"
    kolabd_log_resmgr_minsize="1M"
    kolabd_log_resmgr_complevel="9"
    kolabd_log_freebusy_logfile="@freebusy_logfile@"
    kolabd_log_freebusy_owner="@kolab_usr@"
    kolabd_log_freebusy_group="@kolab_grp@"
    kolabd_log_freebusy_prolog="true"
    kolabd_log_freebusy_epilog="true"
    kolabd_log_freebusy_numfiles="10"
    kolabd_log_freebusy_minsize="1M"
    kolabd_log_freebusy_complevel="9"
    kolabd_log_fbview_logfile="@fbview_logfile@"
    kolabd_log_fbview_owner="@kolab_usr@"
    kolabd_log_fbview_group="@kolab_grp@"
    kolabd_log_fbview_prolog="true"
    kolabd_log_fbview_epilog="true"
    kolabd_log_fbview_numfiles="10"
    kolabd_log_fbview_minsize="1M"
    kolabd_log_fbview_complevel="9"

%common
    kolabd_pidfile="@kolab_pidfile@"
    kolabd_signal () {
        [ -f $kolabd_pidfile ] && kill -$1 `cat $kolabd_pidfile`
    }

%status -u root -o
    kolabd_usable="unknown"
    kolabd_active="no"
    rcService kolabd enable yes && \
        kolabd_signal 0 && kolabd_active="yes"
    echo "kolabd_enable=\"$kolabd_enable\""
    echo "kolabd_usable=\"$kolabd_usable\""
    echo "kolabd_active=\"$kolabd_active\""

%start -p 600 -u @kolab_susr@
    rcService kolabd enable yes || exit 0
    rcService kolabd active yes && exit 0
    @sbindir@/kolabd &
    sleep 5

%stop -p 600 -u @kolab_susr@
    rcService kolabd enable yes || exit 0
    rcService kolabd active no  && exit 0
    kolabd_signal TERM
    sleep 5

%restart -u @kolab_susr@
    rcService kolabd enable yes || exit 0
    rcService kolabd active no  && exit 0
    rc kolabd stop start

%reload -u @kolab_susr@
    rcService kolabd enable yes || exit 0
    rcService kolabd active no  && exit 0
    kolabd_signal HUP
    sleep 5

%daily -u root
    rcService kolabd enable yes || exit 0
    #   rotate logfiles
    shtool rotate -f \
        -n ${kolabd_log_resmgr_numfiles} -s ${kolabd_log_resmgr_minsize} -d \
        -z ${kolabd_log_resmgr_complevel} -m 640 \
	-o ${kolabd_log_resmgr_owner} \
	-g ${kolabd_log_resmgr_group} \
        -P "${kolabd_log_resmgr_prolog}" \
        -E "${kolabd_log_resmgr_epilog}" \
	"${kolabd_log_resmgr_logfile}"
    shtool rotate -f \
        -n ${kolabd_log_freebusy_numfiles} -s ${kolabd_log_freebusy_minsize} -d \
        -z ${kolabd_log_freebusy_complevel} -m 640 \
	-o ${kolabd_log_freebusy_owner} \
	-g ${kolabd_log_freebusy_group} \
        -P "${kolabd_log_freebusy_prolog}" \
        -E "${kolabd_log_freebusy_epilog}" \
	"${kolabd_log_freebusy_logfile}"
    shtool rotate -f \
        -n ${kolabd_log_fbview_numfiles} -s ${kolabd_log_fbview_minsize} -d \
        -z ${kolabd_log_fbview_complevel} -m 640 \
	-o ${kolabd_log_fbview_owner} \
	-g ${kolabd_log_fbview_group} \
        -P "${kolabd_log_fbview_prolog}" \
        -E "${kolabd_log_fbview_epilog}" \
	"${kolabd_log_fbview_logfile}"

--- NEW FILE: workaround.sh.in ---
#!/bin/sh
# (c) 2003 Tassilo Erlewein <tassilo.erlewein at erfrakon.de>
# (c) 2003 Martin Konold <martin.konold at erfrakon.de>
# This program is Free Software under the GNU General Public License (>=v2).
# Read the file COPYING that comes with this packages for details.


@bindir@/cyradm --user manager --password $2 localhost <<EOF
lam $1
quit
EOF

--- kolab DELETED ---

--- kolab_bootstrap DELETED ---

--- kolab_ca.sh DELETED ---

--- kolab_smtpdpolicy DELETED ---

--- kolab_sslcert.sh DELETED ---

--- kolabcheckperm DELETED ---

--- kolabconf DELETED ---

--- kolabd DELETED ---

--- kolabpasswd DELETED ---

--- kolabquotawarn DELETED ---

--- workaround.sh DELETED ---





More information about the commits mailing list