Planet

Subscribe to the RSS feed of this planet! RSS
Timotheus Pokorra's picture
Wed, 2014-09-17 12:33

This describes how to install a docker image of Kolab.

Please note: this is not meant to be for production use. The main purpose is to provide an easy way for demonstration of features and for product validation.

This installation has not been tested a lot, and could still use some fine tuning. This is just a demonstration of what could be done with Docker for Kolab.

Preparing for Docker
I am using a Jiffybox provided by DomainFactory for downloading a Docker container for Kolab 3.3 running on CentOS 6.

I have installed Ubuntu 12.04 LTS on a Jiffybox.
I am therefore following Docker Installation instructions for Ubuntu for the installation instructions:

Install a kernel that is required by Docker:

sudo apt-get update
sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring

After that, in the admin website of JiffyBox, select the custom kernel Bootmanager 64 Bit (pvgrub64); see also the german JiffyBox FAQ. Then restart your JiffyBox.

After the restart, uname -a should show something like:

Linux j89610.servers.jiffybox.net 3.8.0-37-generic #53~precise1-Ubuntu SMP Wed Feb 19 21:37:54 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Now install docker:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
 
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
 
sudo apt-get update
sudo apt-get install lxc-docker

Install container
The image for the container is available here:
https://index.docker.io/u/tpokorra/kolab33_centos6/
If you want to know how this image was created, read my other blog post http://www.pokorra.de/2014/09/building-a-docker-container-for-kolab-3-3-on-jiffybox/.

To install this image, you need to type in this command:

docker pull  tpokorra/kolab33_centos6

You can create a container from this image and run it:

MYAPP=$(sudo docker run --name centos6_kolab33 -p 80:80 -h kolab33.test.example.org -d -t -i tpokorra/kolab33_centos6)

(-P should work instead of -p 80:80 and use the ports defined by EXPOSE in Dockerfile, but that does not work for me at the moment…)

You can see all your containers:

docker ps -a

You now have to attach to the container, and inside the container start the services:

docker attach $MYAPP
  /root/start.sh

Somehow it should work to start the services automatically at startup, but I did not get it to work with CMD or ENTRYPOINT.

To stop the container, type exit on the container’s console, or run from outside:

docker stop $MYAPP

To delete the container:

docker rm $MYAPP

You can reach the Kolab Webadmin on this URL:
http://localhost/kolab-webadmin. Login with user: cn=Directory Manager, password: test

The Webmail interface is available here:
http://localhost/roundcubemail.


Timotheus Pokorra's picture
Wed, 2014-09-17 12:31

This article is an update of the previous post that built a Docker container for Kolab 3.1: Building a Docker container for Kolab on Jiffybox (March 2014)

Preparation
I am using a Jiffybox provided by DomainFactory for building a Docker container for Kolab 3.3 running on CentOS 6.

I have installed Ubuntu 12.04 LTS on a Jiffybox.
I am therefore following Docker Installation instructions for Ubuntu for the installation instructions:

Install a kernel that is required by Docker:

sudo apt-get update
sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring

After that, in the admin website of JiffyBox, select the custom kernel Bootmanager 64 Bit (pvgrub64); see also the german JiffyBox FAQ. Then restart your JiffyBox.

After the restart, uname -a should show something like:

Linux j89610.servers.jiffybox.net 3.8.0-37-generic #53~precise1-Ubuntu SMP Wed Feb 19 21:37:54 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Now install docker:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
 
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
 
sudo apt-get update
sudo apt-get install lxc-docker

Create a Docker image
I realised that if I would install Kolab in one go, the image would become too big to upload to https://index.docker.io.
Therefore I have created a Dockerfile which has several steps for downloading and installing various packages. For a detailed description of a Dockerfile, see the Dockerfile Reference

My Dockerfile looks like this:

FROM centos:centos6
RUN mv /etc/localtime /etc/localtime.old; ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime
RUN echo "NAME=kolab33.test.example.org" > /etc/sysconfig/network; # echo "kolab33.test.example.org" > /proc/sys/kernel/hostname
RUN chmod a+w /dev/shm
WORKDIR /root
RUN yum -y install tar wget
RUN wget -O kolabscripts.tar.gz https://github.com/TBits/KolabScripts/archive/Kolab3.3.tar.gz; tar xzf kolabscripts.tar.gz; rm kolabscripts.tar.gz
WORKDIR /root/KolabScripts-Kolab3.3/kolab
RUN sed -i -e "s/^yum -y install kolab.*/#yum -y install kolab/" reinstallCentOS.sh
RUN echo "y" | ./reinstallCentOS.sh CentOS_6
# split yum -y install kolab into several steps,
# to keep the revisions small enough to avoid problems with uploading the image
RUN yum -y install php-kolabformat
RUN yum -y install mysql-server
RUN yum -y install kolab-cli
RUN yum -y install kolab-imap
RUN yum -y install 389-ds-base
RUN yum -y install java-1.6.0-openjdk
RUN yum -y install libgcj
RUN yum -y install kolab-ldap
RUN yum -y install kolab-webadmin
RUN yum -y install iRony
RUN yum -y install wallace
RUN yum -y install kolab-webclient
RUN yum -y install postfix
RUN yum -y install clamd
RUN yum -y install kolab-mta
RUN yum -y install qt-x11
RUN yum -y install libkolab
RUN yum -y install kolab patch unzip
# prepare for setup kolab
RUN ./initSetupKolabPatches.sh
# we cannot run setup-kolab here, because the hostname is no FQDN
# RUN setup-kolab --default --timezone=Europe/Brussels --directory-manager-pwd=test
# allow connections on port 443 (https)
EXPOSE 443
# TODO: allow IMAP as well
 
#CMD ["/sbin/init"]

This command will build a container with the instructions from the Dockerfile in the current directory. When the instructions have been successful, an image with the name tpokorra/kolab33_centos6 will be created, and the container will be deleted:

sudo docker build -t tpokorra/kolab33_centos6 .

You can see all your local images with this command:

sudo docker images

To finish the container, we need to run setup-kolab, this time we define a hostname as a parameter:

MYAPP=$(sudo docker run --name centos6_kolab33 -h kolab33.test.example.org -d -t -i tpokorra/kolab33_centos6 /bin/bash)
docker attach $MYAPP
# run inside the container:
  echo 2 | setup-kolab --default --timezone=Europe/Brussels --directory-manager-pwd=test
  ./initSSL.sh
  cat > /root/start.sh << EOF
#!/bin/bash
service httpd start
service mysqld start
service dirsrv start
service cyrus-imapd start
sleep 10
service kolabd start
service kolab-saslauthd start
EOF
  chmod a+x /root/start.sh
  service kolabd stop
  service dirsrv stop
  service cyrus-imapd stop
  service mysqld stop
  service httpd stop
  exit

Typing exit inside the container will stop the container.

Now you commit this last manual change:

docker commit $MYAPP tpokorra/kolab33_centos6
# delete the container
docker rm $MYAPP

You can push this image to https://index.docker.io:

#create a new account, or login with existing account:
sudo docker login
sudo docker push tpokorra/kolab33_centos6

You can now see the image available here: https://index.docker.io/u/tpokorra/kolab33_centos6/

See this post Installing Demo Version of Kolab 3.3 with Docker about how to install this image on the same or a different machine, for demo and validation purposes.

Current status: There are still some things not working fine, and I have not tested everything.
But this should be a good starting point for other people as well, to help with a good demo installation of Kolab on Docker.


roundcube's picture
Fri, 2014-09-12 12:40

Roundcube indeed became a huge success story with tens of thousands of installations worldwide. Something I never expected back in 2005 when I started the project as a fresh alternative to the well established but already aged free webmail packages like SquirrelMail or Horde IMP. And now, some 9 years later, we find ourselves in a similar position as the ones we previously wanted to replace. Although we managed to adapt the Roundcube codebase to the ongoing technological innovations, the core architecture is still ruled by the concepts which seemed to be right back when we started. And we’re talking about building a web app for IE 5 and Netscape 6 when browsers weren’t as capable and performant as they are today and when the term AJAX has not yet been known nor did we have nifty libraries such a jQuery or Backbone.js at hand.

It more often happens that, when discussing the implementation of new features to Roundcube, we find ourselves saying “Oh man, that’s going to be an expensive endeavor to squeeze this into our current architecture! If we could just…”. This doesn’t mean that the entire codebase is crap, not at all! But sometimes you just silently wish to give the core a fresh touch which respects the increased requirements and expectations. And that’s the challenge of every software product that has been around for a while and is still intensively developed.

When looking around, I see inspiring new webmail projects slowly emerging which don’t carry the legacy of a software product designed almost a decade ago. I’m truly happy about this development and I appreciate the efforts of honest coders to create the next generation of free webmail software. On the other hand it also makes me a bit jealous to see others starting from scratch and building fast and responsive webmail clients like Mailpile or RainLoop which make Roundcube look like the old dinosaur. Although they’re not yet as feature rich as Roundcube, the core concepts are very convincing and perfectly fit the technological environment we find ourselves in today.

So what if we could start over and build Roundcube from scratch?

Here are some ideas how I could imagine to build a brand new webmail app with todays tools and a 9 years experience in developing web(mail) applications:

  • Do more stuff client side: the entire rendering of the UI should be done in Javascript and no more PHP composing HTML pages loaded in iframes.
  • The server should only become a thin wrapper for talking to backend services like IMAP, LDAP, etc.
  • Maybe even use a common API for client-server communication like the one suggested by Inbox.
  • Design a proper data model which is used by both the server and the client.
  • Separate the data model from the view and use Backbone.js for rendering.
  • Widget-based UI composition using simple HTML structures with small template snippets.
  • Keep mobile, touch and hi-res devices in mind when building the UI.
  • Do skinning solely through CSS and maybe allow single template snippets to be overridden.
  • More abstraction for storage and caching layers to allow alternative backends like MongoDB or Redis.
  • Separate user auth from IMAP. This would allow other sources or accounts to be pulled into one session.
  • Use more 3rd party libraries like require.js, moment.js, jQuery or PHPMailer, Monolog or Doctrine ORM.
  • Contribute to the 3rd party modules rather than re-inventing the wheel.

While this may now sound like a buzzword bingo from a web developers conference (and the list is certainly not complete), I indeed believe in these very useful and well developed modules that are out there at our service. This is what free software development is all about: share, use and contribute.

But finally, not every part of your current Roundcube codebase is badly outdated and should be replaced. I’d definitely keep our current IMAP, LDAP and HTML sanitizing libraries as well as the plugin system which turned out to be a stable and important component and a major contributor to the Roundcube’s success.

And what keeps us from re-building Roundcube from the ground up? Primarily time and the fear of jeopardizing the Roundcube microcosmos with a somewhat incompatible new version that would require every single plugin to be re-written.

But give use funding for 6 month of intense work and let’s see what happens…


Thu, 2014-09-11 15:06

Some time ago I blogged about fighting spam with amavis for the Kolab community. Now the story continues by means of the roundcube integration with amavis.

As earlier mentioned spamassassin is able to store recipient-based preferences in a mysql table with some settings in its local.cf (see spamassassin wiki)

# Spamassassin for Roundcubemail
# http://www.tehinterweb.co.uk/roundcube/#pisauserprefs
user_scores_dsn DBI:mysql:ROUNDCUBEMAILDBNAME:localhost:3306
user_scores_sql_password ROUNCUBEMAILPASSWORD
user_scores_sql_username ROUNDCUBEMAILDBUSERNAME
user_scores_sql_custom_query SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '$GLOBAL' OR username = CONCAT('%',_DOMAIN_) ORDER BY username ASC

However, accessing this with amavis is a real bis problem for many users. Amavis has it’s own user-based configuration policies, but email-plugins as the roundcubemail plugin sauserprefs often only use spamassassin and not amavis. Originally, SA was only called once per message by amavis and therefore recipient-based preferences were not possible at all. This has changed. Now you can use the options @sa_userconf_maps and @sa_username_maps to perform such lookups. Unfortunately these options are still poorly documented. We use them anyway.

The values in @sa_userconf_maps define where amavis has to look for the user preferences. I use mySQL lookups for all recipient addresses.

# use userpref SQL connection from SA local.cf for ALL recipients
@sa_userconf_maps = ({
  '.' => 'sql:'
});

The variable @sa_username_maps tells amavis what to pass to spamassassin as _USERNAME_ (see above) for the mySQL lookup. By default the amavis system user is used. In my setup with Kolab and sauserprefs I use here a regexp which is supposed to match the recipient email-address:

# use recipient email address as _USERNAME_ in userpref mySQL table (_TABLE_)
@sa_username_maps = new_RE (
  [ qr'^([^@]+@.*)'i => '${1}' ]
);

With these additional bits sauserprefs should work. However it seems to me that the string “*** Spam ***”, which should be added to the subject does not work (maybe it does in the most recent version). The thresholds do, though, but better check it carefully.

Did you succeed? Comments are appreciated!

Filed under: Technik Tagged: amavis, Kolab, Roundcubemail, Spamassassin


Andreas Cordes's picture
Thu, 2014-09-04 21:41

Hi,

now I finished compiling all the +Kolab.org packages for the +Raspberry Pi . Just a short note that you can update your groupware on your Pi pto the most recent version of +Kolab.org .

Greetz


Thu, 2014-08-21 14:30

Just in time for the official Kolab 3.3 release, our Gentoo packages for Kolab 3.2 became stable and ready to use. This will clear the way for the upcoming release of Kolab 3.3 for Gentoo. Altough this release won't bring any major changes, it prepares the ground for upcoming developments and new features in Kolab 3.3. Further, with Kolab 3.2 we introduced an upgrade path between Kolab releases for Gentoo and we will try our best to keep updates as consistent and comfortable as possible.
Read more ...


grote's picture
Wed, 2014-08-20 12:19

After extensive beta testing, we are very proud that we can announce the immediate availability of Kolab.org 3.3 today. This release is the one with the most new features of all time.


In a trilogy of articles, we already presented the most exciting new features. All of these would be more than enough for one release, but we still have some new functionality in our sleeves that we have not talked about, yet.


These features include Cross-Folder-Search, a Birthday Calendar that automatically shows the birthdays of all your contacts from your address book in one neat calender. There are now dedicated Out-of-Office settings where you can specify when you are in vacation and which message should be sent under which circumstances. Never again forget to enable or disable your vacation response. Also, in the settings with the Delegation feature, you can now delegate parts of your account to somebody. This is especially useful for people with a huge workload that need help with coordinating appointments for example.



Thanks to extensive testing, issue reporting and fixing by the community this release is both on time and on par. We would like to thank the following people especially for their outstanding contributions: Daniel Hoffend, Aeneas Jaißle and Timotheus Pokorra. If you like to participate as well, there is plenty of possibilities for you.


We will highlight most of the new features below. If you are interested in more details, you are invited to check out the articles from our earlier feature trilogy:


Before you read on for the new features, you might already want to head over to the installation guide, change your repository locations and run an upgrade following the upgrade notes from our documentation.


Email Tags


It is now possible to add tags to email messages. They are shown prominently in the message list before the subject of your mails. In the bottom left corner, there is now a tag cloud where you can select tags, so only emails with those tags are shown to you.


Of course you can also assign colors to your tags and add new tags easily. Our new cross-folder-search feature also works for tags and allows you to show all emails from all folders that have a certain tag.


In the future, we plan on using the new tagging system for all Kolab modules, so the same tags can be used for emails, contacts, events, tasks, etc.



Notes


With Kolab.org 3.3 you will be able to work with notes right in the webclient. As with all things Kolab, you can also have multiple notebooks and share them with people.The notes are automatically synchronized with the Kolab Desktop Client and you will also be able to synchronize them to your mobile devices via the ActiveSync protocol.


Notes can be tagged just like tasks and they can have rich-text content including graphics. They can be printed right from the webclient and also sent via email. In the email view, you can add notes to emails. They are listed at the top of the email preview.


Resource Management


Resources are things like cars, projectors or meeting rooms that can only be used by one group of people at the same time. Kolab.org 3.3 makes it easier to manage your resources.


We added a dedicated resource selection dialog which allows you to search and browse through all the available resources. It displays additional information and attributes for the individual resources as well as an availability calendar based on the free-busy data published for the given resource.


Multiple resource of the same kind can be organized in resource collections (e.g. company cars). If someone wants to book "a car", she books the resource collection for her appointment.



Folder Management


Internally, all address books, calendars, task lists, etc. are folders. So far, we did not hide that fact well from users. Kolab.org 3.3 introduces a new folder navigation view that allows you to search and subscribe to shared calendars, address books, task lists etc. directly from within the respective view.


Searches are also expanded to LDAP, so that search results show folders grouped by matching users. When selecting a "folder" from the search results, your selection can be temporary and affect only the current session or permanently if you always want to see that calendar for example.



Calendar Quickview


The calendar got a quickview mode which allows you to open an undistorted view on a single calendar without unchecking all other calendars from the main view.


When opening the quickview for the new "virtual user calendar", the calendar view displays events from all calendars of that user you have access to. Additionally, it also shows time blocks from anonymized free/busy information where you only know that the user is unavailable during these times.


 


Accessibility Improvements


The entire web client of Kolab.org 3.3 received plenty of improvements that will benefit people that require assistive technologies. The user interface can now be fully operated with the keyboard and has support for screen readers as well as voice output as suggested by the WCAG 2.0 Guidelines and ​WAI ARIA standards.


In the email view for example you are now able to tab through all the button elements, operate the message list and the popup menus. Once the message list gains focus, the arrow keys move the cursor while <space> selects the row and <enter> opens the message. A descriptive block explaining the list navigation was added to the page, so screen readers can pick it up.


Improvements in Kolab Webadmin


We enhanced the Kolab Webadmin to make it even easier to manage the most frequent administrative tasks from a pretty web interface without the need for the command line. You will of course always be able to use the command line if you prefer.


When creating a new Shared Folder, you can directly edit its ACLs giving read rights to certain users or groups for example. Creation is now also done with sane defaults, so the folder can be used immediately.


Organizational Units from LDAP can now be managed right from the Kolab Web Admin as well. Editing their LDAP access rights (ACIs) directly is also possible.


tobru's picture
Sun, 2014-08-10 00:00


Contents

Kolab has released it’s first beta of the upcoming version 3.3.
To test it on Debian I’ve created a Vagrantfile and a small Puppet module which provisions Kolab into a Debian VM. It’s available
on Github.

How to use it

Make sure you have the latest Vagrant version installed. Please see the official documentation.
Clone the git repository with git clone https://github.com/tobru/kolab3-vagrant.git and change into this directory.
Then run vagrant up and wait a while until Vagrant and Puppet have done their jobs. When it’s finished you’re good to enter the VM with vagrant ssh.
To have a working Kolab installation, setup-kolab needs to be called as root (hint: sudo su) once. It configures the Kolab components.
The Kolab Web Admin Panel is now reachable under http://localhost:8080/kolab-webadmin and Roundcube under
http://localhost:8080/roundcubemail.

For more information about how Vagrant works, have a look at the official Getting Started guide.

Chose the Kolab version

By default Kolab will be installed from the development repository where all the latest (and maybe broken) packages are located. To install
a different version, just change the version parameter in manifests/default.pp to the desired version.

Some notes

  • The VM hostname is server.kolab3.dev and is based on chef/debian-7.6 (at this time)
  • Port 8080 on localhos is mapped to port 80 in the VM. No other ports are mapped.
  • MySQL has no password, so while running setup-kolab chose 2: New MySQL server (needs to be initialized) when asked.

PS: Pull requests are always welcome!

Kolab 3 Vagrant box with Puppet provisioning was originally published by Tobias Brunner at tobrunet.ch Techblog on August 10, 2014.


Andreas Cordes's picture
Fri, 2014-08-08 01:06

Hello,

I just finished the compiling of all modules and performed an upgrade to 3.3 beta1 on +Rasperry Pi .

For all impatient:

deb http://kolab.zion-control.org /

Changes I adopted to my installation :

/etc/kolab/kolab.conf

[wallace]
modules = resources, invitationpolicy, footer 
kolab_invitation_policy = ACT_ACCEPT_IF_NO_CONFLICT:zion-control.org, ACT_MANUAL

/etc/kolab-freebusy/config.ini
[httpauth]
type = ldap
host = ldap://localhost:389
bind_dn = "uid=kolab-service,ou=Special Users,dc=zion-control,dc=org"
bind_pw = "IwontTellYou"


[directory "local-cache"]
type = static
fbsource = file:/var/cache/kolab-freebusy/%s.ifb
expires = 10m
[directory "kolab-resources"]
type = ldap
host = ldap://localhost:389
bind_dn = "uid=kolab-service,ou=Special Users,dc=zion-control,dc=org"
bind_pw = "IwontTellYou"
base_dn = "ou=Resources,dc=zion-control,dc=org"
filter = "(&(objectClass=kolabsharedfolder)(mail=%s))"
attributes = mail, kolabtargetfolder
fbsource = "imap://cyrus-admin:IwontTellYou@localhost/%kolabtargetfolder?acl=lrs"
cacheto = /var/cache/kolab-freebusy/%mail.ifb
expires = 10m
loglevel = 100  ; Debug

So far, active-sync still working :-) and no major issues as the ones already known.
More the next days when I performed some tests
Greetz Andreas

Andreas Cordes's picture
Wed, 2014-08-06 14:55

Hi there,

+Kolab  just released the 3.3 beta1 version of kolab. (
My +Raspberry Pi is currently downloading and compiling all the packages.
Because of all the dependencies I solved during the first compile phase, I expect not so much errors during this installation.
Hope to tell you more tomorrow or even on friday.
Greets Andreas

grote's picture
Wed, 2014-08-06 11:15

After we have revealed the new features for Kolab.org 3.3 over the past few weeks, you might have already expected that a beta version is not far away. Today is the day where you can finally get your hands on the brand new 3.3 packages and try out all those new features for yourself.


As our project lead explained on the development list, the release of the final version is aimed for August 20, so you have two weeks to test this beta version thoroughly and help to make sure that no unresolved issues make its way into the final. We would also appreciate if people with test environments could test upgrades especially with existing IMAP spools.


So please warm up your virtual machines and head over to our installation guide. We have provided initial packages for CentOS and Debian. If you are using another distribution, please help to get the packages for those ready in time.


When following the installation guide for CentOS, in order to get the beta packages, please change the repository configuration to:



# cd /etc/yum.repos.d/
# wget http://obs.kolabsys.com:82/Kolab:/Development/CentOS_6/Kolab:Development.repo


When following the installation guide for Debian Wheezy, please change the repository location to



http://obs.kolabsys.com:82/Kolab:/Development/Debian_7.0/


and leave out the updates repository. Currently, there are three known issues for Kolab.org 3.3 beta1 on Debian, but work-arounds exist in the tickets. Please consider helping us resolving those tickets. Here's a helpful guide on how to do this with our Open Build System.


If you find anything, come talk to us in IRC or the development mailing list. When you are sure you found an issue, please report it directly to our issue tracker or just fix it yourself ;)


grote's picture
Tue, 2014-07-22 11:35

With development still in full swing, we are getting closer to a feature freeze and a first beta version of Kolab.org 3.3. In the last weeks, we already shared some details about the new features that will be part of this upcoming Kolab.org version. There will be improved Folder Management and a Calendar Quickview as well as Notes and Accessibility improvements. Now it is time to present two more exciting features that will be part of Kolab.org 3.3.


Pease keep in mind that work is not yet done and that this is only a sneak preview. We hope to have something packaged and ready for you to try out soon!


Email Tags


Tags are little labels that you can attach to objects to categorize them or to find them quicker. We introduced tags with our task module and are now expanding the concept to emails.


You can add tags to email messages and remove them again. The tags can have different colors and are shown prominently in the message list. In the bottom left corner, below the folder list, there is now a tag cloud where you can select tags, so only emails with those tags are shown.


For those interested in the technical details of the the tag implementation, there is a discussion on our format mailing list. In short: A tag is a Kolab Configuration Object of the type 'relation' that stores all tag information and the relation to certain messages. We also considered using IMAP flags, but decided against it for now.


In the future, the new 'kolab_tags' plugin might provide tag handling capabilities to all other plugins that can make use of tags such as calendar, tasklist, notes, etc. The format was already designed in a way that allows for storing relations between any object type.


Resource Management


With Kolab you can also manage resources like cars, presenters or meeting rooms in your organization. People can book resources themselves, if they are available. This ensures that no two groups want to use a meeting room at the same time.


To make this easier, we added a dedicated resource selection dialog as you can see on the right. The new dialog allows you to search and browse through the available resources. It displays additional information and attributes for the individual resources as well as an availability calendar based on the free-busy data published for the given resource.


The automated processing of iTip messages (invitations) to resources was refactored and now supports the fully automated resource booking and updating through the iTip protocol. It wil also be possible to define a booking policy for the resources that for example automatically accepts or refuses booking based on certain criteria.


Multiple resource of the same kind can be organized in resource collections (e.g. company cars). If someone wants to book "a car", she books the resource collection for her appointment. The Wallace module then allocates a concrete resource from that collection and delegates the booking to the next available resource. The delegation is reflected in the iTip replies and the updated user calendar.


 


There will be many various small improvements to the webclient and under the hood, but we will leave it to you to discover those on your own. This means that this will be the last feature presentation. We hope you enjoyed it!


roundcube's picture
Sun, 2014-07-20 02:00

This is the second service release to update the stable version 1.0. It contains
some bug fixes and improvements we considered important for the long term support
branch of Roundcube.

It’s considered stable and we recommend to update all productive installations
of Roundcube with this version. Download it from roundcube.net/download,
see the full changelog here.

Please do backup before updating!


grote's picture
Tue, 2014-07-15 16:28

Last time, we already talked about some new features that are coming with Kolab.org 3.3. Now, we will show you more features we are currently working on. Like last time, this is still work in progress. It is not ready and not packaged for you to try out just yet.


Still, there's more features to come and another post will follow soon. Stay tuned and monitor this channel for more updates.


Notes


Often you just want to note something down real quick. Today, we often use computers for that to have our notes available on all our devices everywhere and searchable.


Currently, it is only possible to work with notes using the Kolab Desktop Client. With Kolab.org 3.3 you will also be able to work with these notes in the webclient. As with all things Kolab, you can also have multiple notebooks and share them with people. The screenshot on the right shows the current state of development and as you can see it already uses the new folder management in the bottom left corner.


The notes are automatically synchronized with the Kolab Desktop Client and you will also be able to synchronize them to your mobile devices via the ActiveSync protocol.


Notes can be tagged just like tasks and they can have rich-text content including graphics. They can be printed right from the webclient and also sent via email.


In the email view, you can add little notes to emails. It will be possible to view and edit your notes before appending them to email messages. If you have notes linked with an email, they are listed at the top of the email preview, like you can see here:



Accessibility improvements


We reviewed and improved our entire web client regarding the accessibility for people that require assistive technologies. The user interface can now be fully operated with the keyboard and has support for screen readers as well as voice output as suggested by the  WCAG 2.0 Guidelines and ​WAI ARIA standards.


As an example, for the email view you are now able to tab through all the button elements, operate the message list and the popup menus. Once the message list gains focus, the arrow keys move the cursor while <space> selects the row and <enter> opens the message. A descriptive block explaining the list navigation was added to the page, so screen readers can pick it up.


All these improvements will make it a lot easier for people that require assistive technologies to use the Kolab webclient. They will also benefit the millions of Roundcube users out there as we strictly bring all our modifications back to the upstream communities.


We hope you enjoyed this quick tour through some of the new Kolab features and are excited about what we will reveal next time.


grote's picture
Wed, 2014-07-09 16:04

The last Kolab.org release was at Valentine's day. So according to our release schedule, the next version should be ready in August. In the past months, we have not been very good at keeping you updated about what we are working on. This is going to change now, because we have made good progress and now finally have something to show.


Please keep in mind that what you are going to see is still work in progress. It is not ready and not packaged for you to try out just yet. Think of it as a first sneak preview of what is going to be Kolab.org 3.3. More will follow. Stay tuned and monitor this channel for more updates.


Folder Management


Internally, all address books, calendars, task lists, etc. are folders. So far, we did not hide that fact well from users. When you wanted to show a folder that you were not subscribed to, you had to go through the folder management that listed all folders equally.


Say hi to the new folder management mechanism we came up with! With Kolab's new folder navigation, shared calendars, address books and task lists can be searched and subscribed to directly from within the respective view. The search box allows you to find "folders" that are shared with you. Searches are also expanded to LDAP, so that search results show folders grouped by matching users. When selecting a "folder" from the search results, your selection can be temporary and affect only the current session or permanently if you always want to see that calendar for example.


Some users spread their events over many calendars (one per team for example) and you might not be interested in the distinction they made. So you have the option to show a "virtual user calendar" that represents an aggregated view on "a user's calendar" and that can be subscribed to as well.



Calendar Quickview


The calendar got a quickview mode which allows you to open an undistorted view on a single calendar without unchecking all other calendars from the main view.


When opening the quickview for a "virtual user calendar" (see above), the calendar view displays events from all calendars of that user you have access to. Additionally, it also shows time blocks from anonymized free/busy information where you only know that the user is unavailable during these times.


Together with the new folder navigation, this new feature makes it even more easy to quickly check whether a certain workmate is available for a phone call or lunch.


We hope you enjoyed this quick tour through two of Kolab's new features and are excited for what more is going to come.


Tue, 2014-07-08 00:00

I have spent some time this weekend investigating SSL certificate-based authentication and implementing it in Kolab web-based user interface.

This topic is very interesting, but definitely too broad to be briefly described in a single blog post, so do not look at it as complete solution, but treat it only as a proof of concept.

Table of contents

Certification Authority

Apache

Kolab - Web-based user interface

Notes

Prepare Certification Authority

At first you need to create Certification Authority on an off-line, and secured system.

I have already created required shell scripts (miniature-octo-ca) to ease the whole operation, so just clone the following repository and move it to the CA system.

$ git clone https://github.com/milosz/miniature-octo-ca.git
Cloning into 'miniature-octo-ca'...
remote: Counting objects: 10, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 10 (delta 2), reused 10 (delta 2)
Unpacking objects: 100% (10/10), done.

Please remember to change working directory before executing any available shell script.

$ cd miniature-octo-ca

Configure Certification Authority

The next step is to configure CA by using common-ca-settings.sh configuration file.

$ vi common-ca-settings.sh 
#!/bin/sh
# common CA settings 

# simple protection - every script can be executed only from current directory
if [ "$(pwd)" != "$(dirname $(readlink -f  $0))" ]; then
  echo "Do not run CA scripts from outside of $(dirname $(readlink -f  $0)) directory"
  exit
fi

# ensure proper permissions by setting umask
umask 077

# kolab secret
# use 'openssl rand -hex 16' command to generate it
kolab_secret="d2d97d097eedb397edea79f52b56ea74"

# key length
key_length=4096

# certificates directory
cert_directory="root-ca"

# number of days to certify the certificate
cert_validfor=3650        # root   certificate
client_cert_validfor=365  # client certificate
server_cert_validfor=365  # server certificate

# default certificate settings
cert_country="PL"
cert_organization="example.org"
cert_state="state"
cert_city="city"
cert_name="example.org CA"
cert_unit="Certificate Authority"
cert_email=""

# certificate number
if [ -f "${cert_directory}/serial" ]; then
  serial=$(cat ${cert_directory}/serial)
fi

You need to modify kolab_secret variable, as it will be used as a key to encrypt/decrypt user password, and common certificate settings to match your setup.

Initialize Certification Authority

Execute prepare_ca.sh shell script to build initial configuration and directory layout.

$ sh prepare_ca.sh 

You can inspect generated OpenSSL configuration (openssl.cnf file) and tune it a bit.

Create root certificate

Execute create_ca.sh shell script to create root certificate and private key.

$ sh create_ca.sh 
Root certificate (private key) password: Generating a 4096 bit RSA private key
............................................................................++
.........................++
writing new private key to 'root-ca/ca/root-key.pem'
-----
No value provided for Subject Attribute emailAddress, skipped

Root certificate and private key will be stored inside root-ca/ca/ directory.

$ ls root-ca/ca/
root-cert.pem  root-key.pem

Create server certificate

Execute add_server.sh shell script to create new server certificate.

$ sh add_server.sh 
Server name (eg. mail.example.com): mail.example.org
Email: admin@example.org
Root certificate (private key) password: 
Server certificate (private key) password: 
Generating a 4096 bit RSA private key
.........++++++
...................++++++
writing new private key to 'root-ca/private/01.pem'
-----
Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Jul  6 12:51:12 2014 GMT
            Not After : Jul  6 12:51:12 2015 GMT
        Subject:
            countryName               = PL
            stateOrProvinceName       = state
            organizationName          = example.org
            organizationalUnitName    = Certificate Authority
            commonName                = mail.example.org
            emailAddress              = admin@example.org
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                EA:3E:05:51:EE:C2:90:53:58:91:E8:D5:56:47:15:7D:5A:26:E8:C4
            X509v3 Authority Key Identifier: 
                keyid:A1:41:B0:72:60:29:1A:9B:B1:63:77:53:E7:93:71:1D:02:14:A4:7C

Certificate is to be certified until Jul  6 12:51:12 2015 GMT (365 days)

Write out database with 1 new entries
[..]
Data Base Updated
writing RSA key

Server certificate and private key (with password removed) will be stored inside root-ca/server_certs/ directory.

$ ls root-ca/server_certs/
01.crt  01.pem

Create client certificate

Execute add_client.sh shell script to create new client certificate.

$ sh add_client.sh 
User name (eg. John Doe): Milosz
Email: milosz@example.org
Export password: 
Kolab password: 
Root certificate (private key) password: 
Client certificate (private key) password: Generating a 4096 bit RSA private key
...++++++
.......++++++
writing new private key to 'root-ca/private/02.pem'
-----
Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Jul  6 12:57:39 2014 GMT
            Not After : Jul  6 12:57:39 2015 GMT
        Subject:
            countryName               = PL
            stateOrProvinceName       = state
            organizationName          = example.org
            organizationalUnitName    = Certificate Authority
            commonName                = Milosz
            emailAddress              = milosz@example.org
            kolabPasswordEnc          = RX3f071sOYKxwDBhNpDVHA==
            kolabPasswordIV           = 72a1e2086a765204122109382f8d4f5d
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                3B:7A:BF:A5:B8:F4:C9:E0:0D:81:41:0D:EE:27:F4:B5:C3:B0:40:67
            X509v3 Authority Key Identifier: 
                keyid:A1:41:B0:72:60:29:1A:9B:B1:63:77:53:E7:93:71:1D:02:14:A4:7C

Certificate is to be certified until Jul  6 12:57:39 2015 GMT (365 days)

Write out database with 1 new entries
[..]
Data Base Updated

Email field will be used to identify user. Kolab password field is a password, that will be encrypted using kolab_secret key, and stored inside certificate file (alongside the initialization vector).

Certificate will be stored inside root-ca/client_certs/ directory, and protected using specified export password (can be easily imported into browser).

$ ls root-ca/client_certs/
02.p12

Apache - Enable HTTPS protocol

Enable SSL module.

# a2enmod ssl
Enabling module ssl.

Enable default SSL virtual host.

# a2ensite default-ssl 
Enabling site default-ssl.

Disable default (non SSL) virtual host.

# a2dissite default
Site default disabled.

Create simple virtual host listening on port 80, to redirect traffic to the HTTPS protocol.

cat << EOF > /etc/apache2/sites-available/default-rewrite
<VirtualHost *:80>
  ServerName mail.example.org
  Redirect / https://mail.example.org/
</VirtualHost>
EOF

Enable the site created above.

# a2ensite default-rewrite 
Enabling site default-rewrite.

Change protocol used by Kolab Files module.

# sed -i -e "s/http:/https:/" /etc/roundcubemail/kolab_files.inc.php

Restart Apache and test applied modifications.

# service apache2 restart

Apache - Switch to own Certification Authority

Create /etc/apache2/ssl/ directory.

# mkdir /etc/apache2/ssl

Copy root certificate root-cert.pem, server certificate server.crt, and server private key server.key to the directory created in the previous step.

Edit Apache configuration to use uploaded server certificate, and private key.

# sed -i -e "/SSLCACertificateFile/ s/#//;s/ssl.crt\/ca-bundle.crt/ssl\/root-cert.pem/" /etc/apache2/sites-available/default-ssl  
# sed -i -e "/SSLCertificateFile/ s/\/etc\/ssl\/certs\/ssl-cert-snakeoil.pem/\/etc\/apache2\/ssl\/server.crt/" /etc/apache2/sites-available/default-ssl
# sed -i -e "/SSLCertificateKeyFile/ s/\/etc\/ssl\/private\/ssl-cert-snakeoil.key/\/etc\/apache2\/ssl\/server.pem/" /etc/apache2/sites-available/default-ssl

Restart web-server and test applied changes.

# service apache2 restart

Import root certificate root-cert.pem into the browser as Certification Authority, then client certificate.

Alter web-server configuration to require valid client certificate, but allow direct API calls from mail server (omit internal error when using kolab-admin).

# sed -i -e "/\/VirtualHost/i <Location />\nSSLRequireSSL\nSSLVerifyClient require\nSSLVerifyDepth 1\nOrder allow,deny\nallow from all\n</Location>\n\n<Location /kolab-webadmin/api/>\nSSLVerifyClient none\norder deny,allow\ndeny from all\nallow from mail.example.org\n</Location>" /etc/apache2/sites-available/default-ssl  

Restart web-server and test client certificate.

# service apache2 restart

Kolab - Use client certificate to fill username filed

You can use client certificate to fill username name inside login form.

to achieve this simple task you need to edit login_form function found in /usr/share/roundcubemail/program/include/rcmail_output_html.php file.

--- /usr/share/roundcubemail/program/include/rcmail_output_html.php.orig	2014-07-06 16:24:08.005325038 +0200
+++ /usr/share/roundcubemail/program/include/rcmail_output_html.php	2014-07-06 16:40:54.429360653 +0200
@@ -1551,40 +1551,47 @@
     protected function login_form($attrib)
     {
         $default_host = $this->config->get('default_host');
         $autocomplete = (int) $this->config->get('login_autocomplete');
 
         $_SESSION['temp'] = true;
 
         // save original url
         $url = rcube_utils::get_input_value('_url', rcube_utils::INPUT_POST);
         if (empty($url) && !preg_match('/_(task|action)=logout/', $_SERVER['QUERY_STRING']))
             $url = $_SERVER['QUERY_STRING'];
 
         // Disable autocapitalization on iPad/iPhone (#1488609)
         $attrib['autocapitalize'] = 'off';
 
+        $email="";
+        if ($_SERVER["HTTPS"] == "on" &&  $_SERVER["SSL_CLIENT_VERIFY"] == "SUCCESS") {
+          if (preg_match('/\/emailAddress=([^\/]*)\//',$_SERVER['SSL_CLIENT_S_DN'],$matches)) {
+            $email=$matches[1];
+          }
+        }
+
         // set atocomplete attribute
         $user_attrib = $autocomplete > 0 ? array() : array('autocomplete' => 'off');
         $host_attrib = $autocomplete > 0 ? array() : array('autocomplete' => 'off');
         $pass_attrib = $autocomplete > 1 ? array() : array('autocomplete' => 'off');
 
         $input_task   = new html_hiddenfield(array('name' => '_task', 'value' => 'login'));
         $input_action = new html_hiddenfield(array('name' => '_action', 'value' => 'login'));
         $input_tzone  = new html_hiddenfield(array('name' => '_timezone', 'id' => 'rcmlogintz', 'value' => '_default_'));
         $input_url    = new html_hiddenfield(array('name' => '_url', 'id' => 'rcmloginurl', 'value' => $url));
-        $input_user   = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser', 'required' => 'required')
+        $input_user   = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser', 'required' => 'required', 'value' => $email)
             + $attrib + $user_attrib);
         $input_pass   = new html_passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'required' => 'required')
             + $attrib + $pass_attrib);
         $input_host   = null;
 
         if (is_array($default_host) && count($default_host) > 1) {
             $input_host = new html_select(array('name' => '_host', 'id' => 'rcmloginhost'));
 
             foreach ($default_host as $key => $value) {
                 if (!is_array($value)) {
                     $input_host->add($value, (is_numeric($key) ? $value : $key));
                 }
                 else {
                     $input_host = null;
                     break;

Use client certificate to login user

Generated client certificate already contains encrypted password (using kolab_secret key) and initialization vector, so you can use them to automatically login user using /usr/share/roundcubemail/index.php file.

--- /usr/share/roundcubemail/index.php.orig	2014-07-06 18:32:40.830414058 +0200
+++ /usr/share/roundcubemail/index.php	2014-07-06 18:37:07.462423513 +0200
@@ -88,17 +88,26 @@
 $RCMAIL->action = $startup['action'];
 
 // try to log in
-if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
-    $request_valid = $_SESSION['temp'] && $RCMAIL->check_request(rcube_utils::INPUT_POST, 'login');
+if ($RCMAIL->task == 'login' && $_SERVER["HTTPS"] == "on" &&  $_SERVER["SSL_CLIENT_VERIFY"] == "SUCCESS") {
+    $request_valid = 1; 
+    if (preg_match('/\/emailAddress=([^\/]*)\//',$_SERVER['SSL_CLIENT_S_DN'],$matches)) {
+      $email=$matches[1];
+    }
+    if (preg_match('/\/1.2.3.4.5.6.7.1=([^\/]*)/',$_SERVER['SSL_CLIENT_S_DN'],$matches)) {
+      $pass=$matches[1];
+    }
+    if (preg_match('/\/1.2.3.4.5.6.7.2=([^\/]*)/',$_SERVER['SSL_CLIENT_S_DN'],$matches)) {
+      $iv=$matches[1];
+    }
+    $pass=rtrim(openssl_decrypt(base64_decode($pass),'aes-128-cbc', hex2bin("d2d97d097eedb397edea79f52b56ea74"), true,hex2bin($iv)));
 
     // purge the session in case of new login when a session already exists 
     $RCMAIL->kill_session();
 
     $auth = $RCMAIL->plugins->exec_hook('authenticate', array(
         'host' => $RCMAIL->autoselect_host(),
-        'user' => trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST)),
-        'pass' => rcube_utils::get_input_value('_pass', rcube_utils::INPUT_POST, true,
-            $RCMAIL->config->get('password_charset', 'ISO-8859-1')),
+        'user' => $email,
+        'pass' => $pass,
         'cookiecheck' => true,
         'valid'       => $request_valid,
     ));

Future improvements

kolab_secret can be stored using Roundcube configuration file, and login form can be modified further to remove input fields, and include more information, .

There should be no problem to add shell script to generate CRL.

PHP code could be simplified a bit.

Please inspect shell scripts to get the idea of additional certificate parameters.


Sat, 2014-07-05 20:32

Apple Clients work best if you create a virtual host for them.

In CentOS create the file /etc/nginx/conf.d/irony.cf

server {
    listen                      443 ssl;
    server_name                 caldav.example.org;



location /
{
    client_max_body_size 30M; # set maximum upload size
    # Make Apple Calendar.app and Contacts.app happy:
    rewrite ^/.well-known/caldav / last;
    rewrite ^/.well-known/carddav / last;
    include fastcgi_params;
    fastcgi_index index.php;
        fastcgi_pass unix:/var/run/php-fpm/kolab.example.org_iRony.sock;
    fastcgi_param SCRIPT_FILENAME /usr/share/iRony/public_html/index.php;
}

}

Edit /usr/share/iRony/config/dav.inc.php or /etc/iRony/dav.inc.php

changes:

// Log DAV requests to <log_dir>/davdebug
$config['base_uri'] = '/';

Restart nginx and choose try manual setup in your Apple Calendar with your virtual host caldav.example.org.


Sat, 2014-07-05 19:58

Create the file /etc/postfix/ldap/virtual_alias_maps_catchall.cf

server_host = localhost
server_port = 389
version = 3
search_base = dc=example,dc=org
scope = sub
domain = ldap:/etc/postfix/ldap/mydestination.cf
bind_dn = uid=kolab-service,ou=Special Users,dc=example,dc=org
bind_pw = PASSWORD_FROM_kolab-service
query_filter = (&(alias=catchall@%d)(objectclass=kolabinetorgperson))
result_attribute = mail

Change dc=example,dc=org twice and the password in this file.

Then edit /etc/postfix/main.cf
add

,   ldap:/etc/postfix/ldap/virtual_alias_maps_catchall.cf

at the end of virtual_alias_maps

In the kolab-webadmin page you can now add a new alias called catchall@domain.org


Thu, 2014-07-03 16:08

This HOWTO is for CentOS 6.5 and Kolab 3.2
Download the Kolab packages but don't run setup-kolab.

Warning: This will not work if you follow this HOWTO:

  • chwala (File Storing)

-- >>>fixed in 3.3

  • Roundcube tasklist does not show created entries (Maybe a bug in Dovecot, Tasklist plugin or configuration problem)

-- >>>fixed in 3.3

  • Delegation
  • Kolab Command-Line Interface!

-- >>>Thomas Baumann wrote how one could maybe list mailboxes with Kolab CLI http://lists.kolab.org/pipermail/users/2014-September/017796.html

  • Roundcube bugs (I solved this with using nginx instead of httpd)

-- >>>fixed in 3.3

Sieve and ACL are also described in this text.

Dependencies

# yum install mercurial
# setup-kolab ldap

Look for the Cyrus Administrator Passwort.
It is needed for the config of the master user in Dovecot. Also Directory
Manager password is needed later in this HOWTO.

Install Dovecot 2.2.13 (stable at time of this HOWTO)

Install and erase old dovecot

# yum install dovecot
# yum erase dovecot

Build dependencies:

# yum install gcc gcc-c++ kernel-devel make
# yum install autoconf automake libtool pkg-config gettext
# yum install openssl-devel openldap-devel
# mkdir -p /root/dovecot && cd /root/dovecot
# hg clone http://hg.dovecot.org/dovecot-2.2/ && cd dovecot-2.2 && hg update -r c55c660d6e9d
# ./autogen.sh
# ./configure --enable-maintainer-mode --with-ldap --sysconfdir=/etc --prefix=/usr --localstatedir=/var --with-ssl=openssl
# make
# make install

When autogen.sh returns autoreconf: /usr/bin/autoconf failed with exit status: 1 you have to run it again.

Dovecot Startscript

Start Dovecot at boot: http://wiki2.dovecot.org/DovecotInit

Install Pigeonhole for Sieve filtering

# cd /root/dovecot
# hg clone http://hg.rename-it.nl/dovecot-2.2-pigeonhole/ && cd dovecot-2.2-pigeonhole && hg update -r 1c6130ff5dd6
# ./autogen.sh
# ./configure --with-dovecot=../dovecot-2.2 --sysconfdir=/etc --prefix=/usr --localstatedir=/var
# make
# make install

Create vmail user

# groupadd -g 5000 vmail
# useradd -g vmail -u 5000 vmail -d /var/vmail -m -s /sbin/nologin

Dovecot configuration

# cp -rf /usr/share/doc/dovecot/example-config/* /etc/dovecot/

Dovecot master user

For the htpasswd command use the password for cyrus-admin from the
setup-kolab ldap.

# htpasswd -c -s /etc/dovecot/master-users cyrus-admin

When asked for New password type in the password of the cyrus admin
twice.

# chown dovecot:dovecot /etc/dovecot/master-users
# chmod 600 /etc/dovecot/master-users

Edit /etc/dovecot/conf.d/auth-master.conf.ext

# Authentication for master users. Included from 10-auth.conf.

# By adding master=yes setting inside a passdb you make the passdb a list
# of "master users", who can log in as anyone else.
# <doc/wiki/Authentication.MasterUsers.txt>

# Example master user passdb using passwd-file. You can use any passdb though.
auth_master_user_separator = *
passdb {
  driver = passwd-file
  args = /etc/dovecot/master-users
  master = yes
  pass = yes
}
passdb {
  driver = shadow
}
userdb {
  driver = passwd
}

Dovecot Auth

Edit conf.d/10-auth.conf

write # in front of !include auth-system.conf.ext and remove the #
before ldap and master

Dovecot LMTP and Auth

add lmtp to protocols in /etc/dovecot/dovecot.conf

/etc/dovecot/conf.d/10-master.conf

service lmtp {
  executable = lmtp

  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    user = postfix
    group = postfix
    mode = 0660
  }

  # Create inet listener only if you can't use the above UNIX socket
  #inet_listener lmtp {
    # Avoid making LMTP visible for the entire internet
    #address =
    #port =
  #}
}

In same file uncomment the lines under Postfix smtp-auth

unix_listener /var/spool/postfix/private/auth {
    mode = 0666
  }

Dovecot metadata

In /etc/dovecot/dovecot.conf

add

imap_metadata = yes
mail_attribute_dict = file:Maildir/dovecot-metadata

Dovecot SSL

# mkdir -p /etc/ssl/private
# openssl req -newkey rsa:4096 -x509 -days 1000 -nodes -out "/etc/ssl/certs/dovecot.pem" -keyout "/etc/ssl/private/dovecot.pem"

Dovecot ldap

Edit dnpass = in this file to the Password of the Directory Manager.

/etc/dovecot/dovecot-ldap.conf.ext

# This file is commonly accessed via passdb {} or userdb {} section in
# conf.d/auth-ldap.conf.ext

# This file is opened as root, so it should be owned by root and mode 0600.
#
# http://wiki2.dovecot.org/AuthDatabase/LDAP
#
# NOTE: If you're not using authentication binds, you'll need to give
# dovecot-auth read access to userPassword field in the LDAP server.
# With OpenLDAP this is done by modifying /etc/ldap/slapd.conf. There should
# already be something like this:

# access to attribute=userPassword
#    by dn="<dovecot's dn>" read # add this
#    by anonymous auth
#    by self write
#    by * none

# Space separated list of LDAP hosts to use. host:port is allowed too.
hosts = localhost

# LDAP URIs to use. You can use this instead of hosts list. Note that this
# setting isn't supported by all LDAP libraries.
#uris =

# Distinguished Name - the username used to login to the LDAP server.
# Leave it commented out to bind anonymously (useful with auth_bind=yes).
dn = cn=Directory Manager

# Password for LDAP server, if dn is specified.
dnpass = PASSWORD

# Use SASL binding instead of the simple binding. Note that this changes
# ldap_version automatically to be 3 if it's lower. Also note that SASL binds
# and auth_bind=yes don't work together.
#sasl_bind = no
# SASL mechanism name to use.
#sasl_mech =
# SASL realm to use.
#sasl_realm =
# SASL authorization ID, ie. the dnpass is for this "master user", but the
# dn is still the logged in user. Normally you want to keep this empty.
#sasl_authz_id =

# Use TLS to connect to the LDAP server.
#tls = no
# TLS options, currently supported only with OpenLDAP:
#tls_ca_cert_file =
#tls_ca_cert_dir =
#tls_cipher_suite =
# TLS cert/key is used only if LDAP server requires a client certificate.
#tls_cert_file =
#tls_key_file =
# Valid values: never, hard, demand, allow, try
#tls_require_cert =

# Use the given ldaprc path.
#ldaprc_path =

# LDAP library debug level as specified by LDAP_DEBUG_* in ldap_log.h.
# -1 = everything. You may need to recompile OpenLDAP with debugging enabled
# to get enough output.
#debug_level = -1

# Use authentication binding for verifying password's validity. This works by
# logging into LDAP server using the username and password given by client.
# The pass_filter is used to find the DN for the user. Note that the pass_attrs
# is still used, only the password field is ignored in it. Before doing any
# search, the binding is switched back to the default DN.
auth_bind = no

# If authentication binding is used, you can save one LDAP request per login
# if users' DN can be specified with a common template. The template can use
# the standard %variables (see user_filter). Note that you can't
# use any pass_attrs if you use this setting.
#
# If you use this setting, it's a good idea to use a different
# dovecot-ldap.conf.ext for userdb (it can even be a symlink, just as long as
# the filename is different in userdb's args). That way one connection is used
# only for LDAP binds and another connection is used for user lookups.
# Otherwise the binding is changed to the default DN before each user lookup.
#
# For example:
#   auth_bind_userdn = cn=%u,ou=people,o=org
#
#auth_bind_userdn =

# LDAP protocol version to use. Likely 2 or 3.
#ldap_version = 3

# LDAP base. %variables can be used here.
# For example: dc=mail, dc=example, dc=org
base = dc=example, dc=org

# Dereference: never, searching, finding, always
#deref = never
deref = searching

# Search scope: base, onelevel, subtree
scope = subtree

# User attributes are given in LDAP-name=dovecot-internal-name list. The
# internal names are:
#   uid - System UID
#   gid - System GID
#   home - Home directory
#   mail - Mail location
#
# There are also other special fields which can be returned, see
# http://wiki2.dovecot.org/UserDatabase/ExtraFields
#user_attrs = homeDirectory=home,uidNumber=uid,gidNumber=gid
user_attrs =uid= mail,uid=home=/var/vmail/%d/%{ldap:uid}


# Filter for user lookup. Some variables can be used (see
# http://wiki2.dovecot.org/Variables for full list):
#   %u - username
#   %n - user part in user@domain, same as %u if there's no domain
#   %d - domain part in user@domain, empty if user there's no domain
#user_filter = (&(objectClass=posixAccount)(uid=%u))
#user_filter = (|(&((uid=%u))(&(|(uid=%n)(mail=%u))(objectclass=kolabinetorgperson)))
#user_filter = (&(|(uid=%n)(mail=%u))(objectclass=kolabinetorgperson))
user_filter = (|(uid=%n)(mail=%u))



# Password checking attributes:
#  user: Virtual user name (user@domain), if you wish to change the
#    user-given username to something else
#  password: Password, may optionally start with {type}, eg. {crypt}
# There are also other special fields which can be returned, see
# http://wiki2.dovecot.org/PasswordDatabase/ExtraFields
#pass_attrs = uid=user,userPassword=password
pass_attrs = uid=user,userPassword=password,=user=%{ldap:mail}


# If you wish to avoid two LDAP lookups (passdb + userdb), you can use
# userdb prefetch instead of userdb ldap in dovecot.conf. In that case you'll
# also have to include user_attrs in pass_attrs field prefixed with "userdb_"
# string. For example:
#pass_attrs = uid=user,userPassword=password,\
#  homeDirectory=userdb_home,uidNumber=userdb_uid,gidNumber=userdb_gid

# Filter for password lookups
#pass_filter = (&(objectClass=posixAccount)(uid=%u))
#pass_filter = (&(|(uid=%n)(mail=%u))(objectclass=kolabinetorgperson))
pass_filter = (|(uid=%n)(mail=%u))

# Attributes and filter to get a list of all users
#iterate_attrs = uid=user
#iterate_filter = (objectClass=posixAccount)
iterate_attrs = uid=user
iterate_filter = (objectClass=kolabinetorgperson)

# Default password scheme. "{scheme}" before password overrides this.
# List of supported schemes is in: http://wiki2.dovecot.org/Authentication
#default_pass_scheme = CRYPT
default_pass_scheme = SSHA

Dovecot 10-mail.conf

mail_uid = 5000
mail_gid = 5000

mail_location = maildir:~/Maildir

Postfix main.cf

replace lines with ".pem" with
smtpd_tls_cert_file=/etc/ssl/certs/dovecot.pem smtpd_tls_key_file=/etc/ssl/private/dovecot.pem

SASL auth via dovecot. add to main.cf:

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain =
broken_sasl_auth_clients = yes

Kolab setup

# setup-kolab mysql
# setup-kolab php
# setup-kolab mta
# setup-kolab kolabd
# setup-kolab roundcube
# setup-kolab syncroton
# setup-kolab freebusy

LMTP

edit /etc/postfix/ldap/transport_maps.cf

result_format = lmtp:unix:private/dovecot-lmtp

for Kolab 3.3 (maybe also 3.2):
edit /etc/postfix/transport

::
shared@example.org lmtp:unix:/var/spool/postfix/private/dovecot-lmtp

then run postmap transport

Dovecot ACL for sharing mailboxes

in 10-mail.conf change (if empty) mail_plugins to
mail_plugins = $mail_plugins acl

add to doveconf.conf

protocol imap {
  mail_plugins = $mail_plugins imap_acl
}

plugin {
  # Without global ACLs:
  acl = vfile

  # With global ACL files in /etc/dovecot/dovecot-acls file (v2.2.11+):
  #acl = vfile:/etc/dovecot/dovecot-acl

  # With global ACLs in /etc/dovecot/acls/ directory (obsolete):
  #acl = vfile:/etc/dovecot/acls
}

Edit 10-mail.conf. Search for namespace inbox and change the
seperator to /

Search for "shared namespace configuration".

Also change seperator to / and prefix = "Shared Folders/%%u/"

and location = maildir:%%h/Maildir:INDEX=~/Maildir/shared/%%u

Don't change the prefix Shared Folders or Roundcube won't recognize this as a shared folder for calendars or other types.

Example configuration:

namespace inbox {
  # Namespace type: private, shared or public
  #type = private

  # Hierarchy separator to use. You should use the same separator for all
  # namespaces or some clients get confused. '/' is usually a good one.
  # The default however depends on the underlying mail storage format.
  separator = /

  # Prefix required to access this namespace. This needs to be different for
  # all namespaces. For example "Public/".
  #prefix =

  # Physical location of the mailbox. This is in same format as
  # mail_location, which is also the default for it.
  #location =

  # There can be only one INBOX, and this setting defines which namespace
  # has it.
  inbox = yes

  # If namespace is hidden, it's not advertised to clients via NAMESPACE
  # extension. You'll most likely also want to set list=no. This is mostly
  # useful when converting from another server with different namespaces which
  # you want to deprecate but still keep working. For example you can create
  # hidden namespaces with prefixes "~/mail/", "~%u/mail/" and "mail/".
  #hidden = no

  # Show the mailboxes under this namespace with LIST command. This makes the
  # namespace visible for clients that don't support NAMESPACE extension.
  # "children" value lists child mailboxes, but hides the namespace prefix.
  #list = yes

  # Namespace handles its own subscriptions. If set to "no", the parent
  # namespace handles them (empty prefix should always have this as "yes")
  #subscriptions = yes
}
# Example shared namespace configuration
namespace {
  type = shared
  separator = /
  # Mailboxes are visible under "shared/user@domain/"
  # %%n, %%d and %%u are expanded to the destination user.
  #prefix = shared/%%u/
  #Kolab Prefix
  prefix = "Shared Folders/%%u/"

  # Mail location for other users' mailboxes. Note that %variables and ~/
  # expands to the logged in user's data. %%n, %%d, %%u and %%h expand to the
  # destination user's data.
  location = "maildir:%%h/Maildir:INDEX=~/Maildir/Shared Folders/%%u"

  # Use the default namespace for saving subscriptions.
  #subscriptions = no

  # List the shared/ namespace only if there are visible shared mailboxes.
  list = children
}
# chown vmail:vmail /var/lib/dovecot
# mkdir -p /var/lib/dovecot/db
# chown vmail:vmail /var/lib/dovecot/db
# chmod 0770 /var/lib/dovecot/db
# touch /var/lib/dovecot/db/shared-mailboxes.db
# chown vmail:vmail /var/lib/dovecot/db/shared-mailboxes.db

Configure in conf.d/90-acl.conf if you want users to be able to share to
users of all domains

plugin {
  acl_shared_dict = file:/var/lib/dovecot/db/shared-mailboxes.db
}

For multiple separated databases or to allow users to share to anyone:
http://wiki2.dovecot.org/SharedMailboxes/Shared

Edit 10-master.conf look for auth-userdb and change it to this

unix_listener auth-userdb {
    #mode = 0666
    user = vmail
    group = vmail
  }

In 10-master.conf look for service dict change to:

service dict {
  # If dict proxy is used, mail processes should have access to its socket.
  # For example: mode=0660, group=vmail and global mail_access_groups=vmail
  unix_listener dict { #0600
    mode = 0666
    user = vmail
    group = vmail
  }
}

Dovecot sieve

Edit 90-sieve.conf

change the following

sieve = ~/.dovecot.sieve
sieve_dir = ~/sieve

Edit 20-managesieve.conf Uncomment protocols = $protocols sieve

Uncomment and edit:

service managesieve-login {
  inet_listener sieve {
     address = 127.0.0.1 ::1
     port = 4190
  }

  #inet_listener sieve_deprecated {
  #  port = 2000
  #}

  # Number of connections to handle before starting a new process. Typically
  # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
  # is faster. <doc/wiki/LoginProcess.txt>
  #service_count = 1

  # Number of processes to always keep waiting for more connections.
  #process_min_avail = 0

  # If you set service_count=0, you probably need to grow this.
  #vsz_limit = 64M
}

service managesieve {
  # Max. number of ManageSieve processes (connections)
  #process_limit = 1024
}

Since my managesieve only listens to localhost I had to edit
/usr/share/roundcubemail/plugins/managesieve/config.inc.php

$config['managesieve_host'] = '127.0.0.1';

Edit Dovecot's 15-lda.conf and add sieve to mail_plugins

protocol lda {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins sieve
}

Edit Dovecot's 15-lmtp.conf and add sieve to mail_plugins

protocol lda {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins sieve
}

Sun, 2014-06-22 00:00

After a longer period of time I have decided to install Kolab and use it as personal information manager. Installation process went as expected up to the point where setup process tried to install Roundcube database and failed miserably.

Source of the problem

The problem can be easily identified by the error messages returned by the setup process.

Follow the example below to see MySQL errors at the very end.

# setup-kolab 

Please supply a password for the LDAP administrator user 'admin', used to login
to the graphical console of 389 Directory server.

Administrator password [Sii79iQyU3gkHN3]: 

Please supply a password for the LDAP Directory Manager user, which is the
administrator user you will be using to at least initially log in to the Web
Admin, and that Kolab uses to perform administrative tasks.

Directory Manager password [nNQAwQVnSDRzSUq]: 

Please choose the system user and group the service should use to run under.
These should be existing, unprivileged, local system POSIX accounts with no
shell.

User [dirsrv]: 
Group [dirsrv]: 

This setup procedure plans to set up Kolab Groupware for the following domain
name space. This domain name is obtained from the reverse DNS entry on your
network interface. Please confirm this is the appropriate domain name space.

sleeplessbeastie.eu [Y/n]: 

The standard root dn we composed for you follows. Please confirm this is the root
dn you wish to use.

dc=sleeplessbeastie,dc=eu [Y/n]: 

Setup is now going to set up the 389 Directory Server. This may take a little
while (during which period there is no output and no progress indication).

[..]

Please supply a Cyrus Administrator password. This password is used by Kolab to
execute administrative tasks in Cyrus IMAP. You may also need the password
yourself to troubleshoot Cyrus IMAP and/or perform other administrative tasks
against Cyrus IMAP directly.

Cyrus Administrator password [qolmP-8qsQAiPRe]: 

Please supply a Kolab Service account password. This account is used by various
services such as Postfix, and Roundcube, as anonymous binds to the LDAP server
will not be allowed.

Kolab Service password [yp48IyJvn8rd12H]: 

[..]

What MySQL server are we setting up?
 - 1: Existing MySQL server (with root password already set).
 - 2: New MySQL server (needs to be initialized).
Choice: 1

Please supply the root password for MySQL, so we can set up user accounts for
other components that use MySQL.

MySQL root password: 

Please supply a password for the MySQL user 'kolab'. This password will be used
by Kolab services, such as the Web Administration Panel.

MySQL kolab password [LAOv8Gmn2l1Gs-G]: 

Please supply the timezone PHP should be using. You have to use a Continent or
Country / City locality name like 'Europe/Berlin', but not just 'CEST'.

Timezone ID [UTC]: 

Please supply a password for the MySQL user 'roundcube'. This password will be
used by the Roundcube webmail interface.

MySQL roundcube password [yP7R_m4wJVcNiDW]: 
ERROR 1005 (HY000) at line 9: Can't create table 'roundcube.kolab_alarms' (errno: 150)
ERROR 1146 (42S02) at line 179: Table 'roundcube.system' doesn't exist

[..]

These errors are generated due to the following code inside /usr/share/pyshared/pykolab/setup/setup_roundcube.py file.

    schema_files = []
    for root, directories, filenames in os.walk('/usr/share/doc/'):
        for directory in directories:
            if directory.startswith("roundcubemail"):
                for root, directories, filenames in os.walk(os.path.join(root, directory)):
                    for filename in filenames:
                        if filename.startswith('mysql.initial') and filename.endswith('.sql'):
                            schema_filepath = os.path.join(root,filename)
                            if not schema_filepath in schema_files:
                                schema_files.append(schema_filepath)

                break
        break

I assume that its goal is to recursively find every mysql.initial*.sql file inside /usr/share/doc/roundcubemail*/ directories.

Finding the solution

First approach - Problem identification

Copy the earlier mentioned code to the disctinct script and slightly modify it to output additional information.

$ cat first_code_check.py 
import os

schema_files = []
for root, directories, filenames in os.walk('/usr/share/doc/'):
  for directory in directories:
    if directory.startswith("roundcubemail"):
      print "-> " + directory + " (" + root + ")"
      for root, directories, filenames in os.walk(os.path.join(root, directory)):
        for filename in filenames:
          print "   \ " + filename
          if filename.startswith('mysql.initial') and filename.endswith('.sql'):
            schema_filepath = os.path.join(root,filename)
            if not schema_filepath in schema_files:
              schema_files.append(schema_filepath)

It is easy to notice the problem after the script execution - the root variable inside third for loop is messing with future iterations.

$ python first_code_check.py 
-> roundcubemail-plugins-kolab (/usr/share/doc/)
   \ changelog.Debian.gz
   \ copyright
-> roundcubemail-plugin-threadingasdefault (/usr/share/doc/roundcubemail-plugins-kolab)
-> roundcubemail (/usr/share/doc/roundcubemail-plugins-kolab)

Second approach - Python script

The most obious fix is to rename second occurence of the root variable.

$ cat second_code_check.py 
import os

schema_files = []
for root, directories, filenames in os.walk('/usr/share/doc/'):
  for directory in directories:
    if directory.startswith("roundcubemail"):
      print "-> " + directory + "(" + root + ")"
      for nested_root, directories, filenames in os.walk(os.path.join(root, directory)):
        for filename in filenames:
          print "   \ " + filename
          if filename.startswith('mysql.initial') and filename.endswith('.sql'):
            schema_filepath = os.path.join(nested_root,filename)
            if not schema_filepath in schema_files:
              schema_files.append(schema_filepath)
              print "     ! added schema file"

Simple test reveals that it works as expected.

$ python second_code_check.py
-> roundcubemail-plugins-kolab(/usr/share/doc/)
   \ changelog.Debian.gz
   \ copyright
-> roundcubemail-plugin-threadingasdefault(/usr/share/doc/)
   \ changelog.Debian.gz
   \ copyright
-> roundcubemail(/usr/share/doc/)
   \ mysql.initial.sql
    ! added schema file
   \ mssql.initial.sql
   \ README.md
   \ sqlite.initial.sql
   \ changelog.Debian.gz
   \ copyright
   \ postgres.initial.sql
-> roundcubemail-plugin-contextmenu(/usr/share/doc/)
   \ changelog.gz
   \ changelog.Debian.gz
   \ copyright

Second approach - Path

--- /usr/share/pyshared/pykolab/setup/setup_roundcube.py.orig	2014-06-21 18:43:40.975058719 +0200
+++ /usr/share/pyshared/pykolab/setup/setup_roundcube.py	2014-06-21 19:12:46.957149746 +0200
@@ -139,16 +139,13 @@
     for root, directories, filenames in os.walk('/usr/share/doc/'):
         for directory in directories:
             if directory.startswith("roundcubemail"):
-                for root, directories, filenames in os.walk(os.path.join(root, directory)):
+                for nested_root, directories, filenames in os.walk(os.path.join(root, directory)):
                     for filename in filenames:
                         if filename.startswith('mysql.initial') and filename.endswith('.sql'):
-                            schema_filepath = os.path.join(root,filename)
+                            schema_filepath = os.path.join(nested_root,filename)
                             if not schema_filepath in schema_files:
                                 schema_files.append(schema_filepath)
 
-                break
-        break
-
     if os.path.isdir('/usr/share/roundcubemail'):
         rcpath = '/usr/share/roundcubemail/'
     elif os.path.isdir('/usr/share/roundcube'):

Third approach - Python script

This could be simplified a bit by replacing problematic os.walk call.

$ cat third_code_check.py 
import os
import fnmatch

schema_files = []
for root, directories, filenames in os.walk('/usr/share/doc/'):
  for directory in directories:
    if directory.startswith("roundcubemail"):
      print "-> " + directory + "(" + root + ")"
      for filename in os.listdir(os.path.join(root, directory)):
        if fnmatch.fnmatch(filename, 'mysql.initial*.sql'):
          schema_filepath = os.path.join(root,directory,filename)
          if not schema_filepath in schema_files:
            schema_files.append(schema_filepath)
            print "  \ " + filename
$ python third_code_check.py 
-> roundcubemail-plugins-kolab (/usr/share/doc/)
-> roundcubemail-plugin-threadingasdefault (/usr/share/doc/)
-> roundcubemail (/usr/share/doc/)
  \ mysql.initial.sql
-> roundcubemail-plugin-contextmenu (/usr/share/doc/)

Third approach - Patch

--- /usr/share/pyshared/pykolab/setup/setup_roundcube.py.orig	2014-06-21 18:43:40.975058719 +0200
+++ /usr/share/pyshared/pykolab/setup/setup_roundcube.py	2014-06-21 19:43:14.235162418 +0200
@@ -20,6 +20,7 @@
 from Cheetah.Template import Template
 import hashlib
 import os
+import fnmatch
 import random
 import re
 import subprocess
@@ -139,15 +140,11 @@
     for root, directories, filenames in os.walk('/usr/share/doc/'):
         for directory in directories:
             if directory.startswith("roundcubemail"):
-                for root, directories, filenames in os.walk(os.path.join(root, directory)):
-                    for filename in filenames:
-                        if filename.startswith('mysql.initial') and filename.endswith('.sql'):
-                            schema_filepath = os.path.join(root,filename)
-                            if not schema_filepath in schema_files:
-                                schema_files.append(schema_filepath)
-
-                break
-        break
+                for filename in os.listdir(os.path.join(root, directory)):
+                    if fnmatch.fnmatch(filename, 'mysql.initial*.sql'):
+                        schema_filepath = os.path.join(root,directory,filename)
+                        if not schema_filepath in schema_files:
+                            schema_files.append(schema_filepath)
 
     if os.path.isdir('/usr/share/roundcubemail'):
         rcpath = '/usr/share/roundcubemail/'

Fourth approach - Python script

This code can be simplified further by not reading directories recursively.

$ cat fourth_code_check.py
import os
import fnmatch
import glob

schema_files = []
for directory in glob.glob('/usr/share/doc/roundcubemail*'):
  print "-> " + directory
  for filename in os.listdir(directory):
    if fnmatch.fnmatch(filename, 'mysql.initial*.sql'):
      schema_filepath = os.path.join(directory,filename)
      if not schema_filepath in schema_files:
        schema_files.append(schema_filepath)
        print "  \ " + filename
$ python fourth_code_check.py 
-> roundcubemail-plugins-kolab (/usr/share/doc/)
-> roundcubemail-plugin-threadingasdefault (/usr/share/doc/)
-> roundcubemail (/usr/share/doc/)
  \ mysql.initial.sql
-> roundcubemail-plugin-contextmenu (/usr/share/doc/)

Fourth approach - Patch

--- /usr/share/pyshared/pykolab/setup/setup_roundcube.py.orig	2014-06-21 18:43:40.975058719 +0200
+++ /usr/share/pyshared/pykolab/setup/setup_roundcube.py	2014-06-21 19:59:42.380040035 +0200
@@ -20,6 +20,8 @@
 from Cheetah.Template import Template
 import hashlib
 import os
+import glob
+import fnmatch
 import random
 import re
 import subprocess
@@ -136,18 +138,12 @@
             fp.close()
 
     schema_files = []
-    for root, directories, filenames in os.walk('/usr/share/doc/'):
-        for directory in directories:
-            if directory.startswith("roundcubemail"):
-                for root, directories, filenames in os.walk(os.path.join(root, directory)):
-                    for filename in filenames:
-                        if filename.startswith('mysql.initial') and filename.endswith('.sql'):
-                            schema_filepath = os.path.join(root,filename)
-                            if not schema_filepath in schema_files:
-                                schema_files.append(schema_filepath)
-
-                break
-        break
+    for directory in glob.glob('/usr/share/doc/roundcubemail*'):
+        for filename in os.listdir(directory):
+            if fnmatch.fnmatch(filename, 'mysql.initial*.sql'):
+                schema_filepath = os.path.join(directory,filename)
+                if not schema_filepath in schema_files:
+                    schema_files.append(schema_filepath)
 
     if os.path.isdir('/usr/share/roundcubemail'):
         rcpath = '/usr/share/roundcubemail/'

Ending notes

I am not a Python developer. I wrote about this issue as it was an interesting way to learn about directory traversal and file filtering implemented in Python language.

It is up to you to decide which solution is appropriate for you - for more recent information please read the official bug report.


mollekopf's picture
Wed, 2014-05-21 12:40

Wouldn’t it be great if Kontact would allow you to select a set of folders you’re interested in, that setting would automatically be respected by all your devices and you’d still be able to control for each individual folder whether it should be visible and available offline?

I’ll line out a system that allows you to achieve just that in a groupware environment. I’ll take Kolab and calendar folders as example, but the concept applies to all groupware systems and is just as well applicable to email or other groupware content.

User Scenarios

  •  Anna has access to hundreds of shared calendars, but she usually only uses a few selected ones. She therefore only has a subset of the available calendars enabled, that are shown to her in the calendar selection dialog, available for offline usage and also get synchronized to her mobile phone. If she realizes she no longer requires a calendar, she simply disables it and it disappears from the Kontact, the Webclient and her phone.
  • Joe works with a small team that shares their calendars with him. Usually he only uses the shared team-calendar, but sometimes he wants to quickly check if they are in the office before calling them, and he’s often doing this in the train with unreliable internet connection. He therefore disables the team member’s calendars but still enables synchronization for them. This hides the calendars from all his devices, but he still can quickly enable them on his laptop while being offline.
  • Fred has a mailing list folder that he always reads on his mobile, but never on his laptop. He keeps the folder enabled, but hides it on his laptop so his folder list isn’t unnecessarily cluttered.

What these scenarios tell us is that we need a flexible mechanism to specify the folders we want to see and the folders we want synchronized. Additionally we want, in today’s world where we have multiple devices, to synchronize the selection of folders that are important to us. It is likely I’d like to see the calendar I have just enabled in Kontact also on my phone. However, we always want to keep the possibility to alter that default setting on specific devices.

Current State

If you’re using a Kolab Server, you can use IMAP subscriptions to control what folders you want to see on your devices. Kontact currently respects that setting in that it makes all folders visible and available for offline usage. Additionally you have local subscriptions to disable certain folders (so they are not downloaded or displayed) on a specific device. That is not very flexible though, and personally I ended up having pretty much all folders enabled that I ever used, leading to cluttered folder selections and lot’s of bandwith and storage space used to keep everything available offline.

To change the subscription state, KMail offers to open the IMAP-subscription dialog which allows to toggle the subscription state of individual folders. This works, but is not well integrated (it’s a separate dialog), and is also not well integrable since it’s IMAP specific.

Because the solution is not well integrated, it tends to be rather static in my experience. I tend to subscribe to all folders that I ever use, which results in a very long and cluttered folder-list.

A new integrated subscription system

What would be much better, is if the back-end could provide a default setting that is synchronized to the server, and we could quickly enable or disable folders as we require them. Additionally we can override the default settings for each individual folder to optimize our setup as required.

To make the system more flexible, while not unnecessarily complex, we need a per folder setting that allows to override a backend provided default value. Additionally we need an interface for applications to alter the subscription state through Akonadi (instead of bypassing it). This allows for a well integrated solution that doesn’t rely on a separate, IMAP-specific dialog.

Each folder requires the following settings:

  • An enabled/disabled state that provides the default value for synchronizing and displaying a folder.
  • An explicit preference to synchronize a folder.
  • An explicit preference to make a folder visible.

A folder is visible if:

  • There is an explicit preference that the folder is visible.
  • There is no explicit preference on visibility and the folder is enabled.

A folder is synchronized if:

  • There is an explicit preference that the folder is synchronized.
  • There is no explicit preference on synchronization and the folder is enabled.

The resource-backend can synchronize the enabled/disabled state which should give a default experience as expected. Additionally it is possible to override that default state using the explicit preference on a per folder level.

User Interaction

By default you would be working with the enabled/disabled state, that is synchronized by the resource backend. If you enable a folder it becomes visible and synchronized, if you disable it, it becomes invisible and not synchronized. For the enabled/disabled state we can build a very easy user interface, as it is a single boolean state, that we can integrate into the primary UI.

Because the enabled/disabled state is synchronized, an enabled calendar will automatically appear on your MyKolab.com web interface and your mobile. One click, and you’re all set.

Mockup of folder sync properties

Example mockup of folder sync properties

In the advanced settings, you can then override visibility and synchronization preference at will as a local-only setting, giving you full flexibility. This can be hidden in a properties dialog, so it doesn’t clutter the primary UI.

This makes the default usecase very simple to use (you either want a folder or you don’t want it), while we keep full flexibility in overriding the default behaviour.

IMAP Synchronization

The IMAP resource will synchronize the enabled/disabled state with IMAP subscriptions if you have subscriptions enabled in the resource. This way we can use the enabled/disabled state as interface to change the subscriptions, and don’t have to use a separate dialog to toggle that state.

Interaction with existing mechanisms

This mechanism can probably replace local subscriptions eventually. However, in order not to break existing setups I plan to leave local subscriptions working as they currently are.

Conclusion

By implementing this proposal we get the required flexibility to make sure the resources of our machine are optimally used, while different clients still interact with each other as expected. Additionally we gain a uniform interface to enable/disable a collection that can be synchronized by backends (e.g. using the IMAP subscription state). This will allow applications to nicely integrate this setting, and should therefore make this feature a lot easier to use and overall more agile.

New doors are opened as this will enable us to do on-demand loading of folders. By having the complete folder list available locally (but disabled by default and thus hidden), we can use the collections to load their content temporarily and on-demand. Want to quickly look at that shared calendar you don’t have enabled? Simply search for it and have a quick look, the data is synchronized on-demand and the folder is as quickly gone as you found it, once it is no longer required. This will diminish the requirement to have folders constantly clutter your folder list even further.

So, what do you think?


roundcube's picture
Sun, 2014-05-11 02:00

This is the first service release to update the stable version 1.0. It contains
some important bug fixes and improvements, mainly a fix for the unintentional
redirect from the compose page in Google Chrome which started to happen after
a recent Chrome update.

It’s considered stable and we recommend to update all productive installations
of Roundcube with this version. Download it from roundcube.net/download,
see the full changelog here.

Please note that the update includes a small database schema change so make sure
you run the update script.


DSP3's picture
Mon, 2014-05-05 15:43

Kolab is an excellent open source messaging and collaboration suite, the installation of which I discussed in a previous post.

Currently, there is one feature missing from the Kolab suite and that is the ability to send instant messages (IM) between authenticated Kolab users or even outside of the domain. This is where ejabbered comes in. The following is a summary of how you can integrate ejabberd into a Kolab system running on CentOS 6.5

As Kolab is already installed, there is no need to add the EPEL repository used to host the ejabbered .rpm installer. Installation is as simple as:

sudo yum install ejabberd

Ejabbered is written in Erlang and is configured by editing /etc/ejabbered/ejabberd.cfg

sudo nano /etc/ejabberd/ejabberd.cfg

Search for the following code and edit accordingly:

%%{auth_method, internal}.

change to

{auth_method, ldap}.

Search for the remaining lines of code ('ctrl' + 'w' in nano) and change them to fit your environment:

{ldap_servers, ["localhost"]}.
{ldap_port, 389}.
{ldap_rootdn, "cn=Directory Manager"}.
{ldap_password, "the_password_you_set_during_kolab_install_for_ldap"}.
{ldap_filter, "(objectClass=mailrecipient)"}.
{ldap_uids, [{"alias", "%u@%d"}]}.
{acl, admin, {user, "admin", "yourdomain.org"}}.
{hosts, ["yourdomain.org"]}.
{ldap_base, "ou=People,dc=yourdomain,dc=org"}.

Save the file by ctrl 'x' and then pressing 'y' (yes) and enter.
Start ejabberd service

sudo service ejabberd start

Add ejabberd as a service to start at boot

chkconfig ejabberd on

Update iptables

sudo iptables -I INPUT -ptcp --dport 5280 -j ACCEPT
sudo iptables -I INPUT -ptcp --dport 5222 -j ACCEPT
sudo service iptables save
sudo service iptables restart

You should now be able to login with your IM client such as Jitsi or Pidgin. As ejabberd is set to use ldap_uids with 'alias' you can login with an alias instead of firstname.lastname@yourdaomain.org

Test the security of your ejabberd install using the IM Observatory. Sample result for client to server connections should like like this:
xmpp.net score
High client to server scores (c2s) are essential (A). Server to server (s2s) can be hampered by many xmpp servers (including Gmail) not allowing TLS connections (tls_required), therefore this must be set as optional in the ejabbered.cfg and will lower your score (B).

You now have an excellent communication and collaboration system. Voice, video, email, IM, calendar, address book, file share. Source code freely available, so adapt to your requirements.

Original credit goes to Andreas Cordes for assistance with ldap authentication with ejabberd.


Mon, 2014-05-05 11:57

This week, Kolab.org will be presented at two conferences. The first one will show how Kolab can be a secure privacy asylum in a post-Snowden world. It will highlight Kolab's security architecture and show how you can run Kolab on a Rasperry Pi for yourself or in full blown datacenter for millions of users. The presentation will happen in Berlin at Linuxtag on Thursday May 8 on Stage B at 18:30.

If you can not afford the entry to Linuxtag, you will be happy to find out that there is free entry at 18:00 right before the Kolab.org presentation.

The second presentation takes place in Porto Alegre, Brazil at the International Free Software forum (FISL). This year's motto is Security and Privacy: Free Software in the struggle against Espionage. This topic would of course not be complete without Kolab. So our community manager Torsten will give a general introduction into Kolab, it's architecture and community. He will also motivate people to join our still lonely Portuguese community mailing list.

The talk will take place on Saturday May 10 in room 40T at 15:00. If you happen to be at FISL, make sure not to miss it.


Andreas Cordes's picture
Sun, 2014-05-04 00:15

Since now I'm using +Kolab on my +Raspberry Pi  for 100 days.

Syncroton (Active-Sync) is working like a charme, access to my files via WebDav is also working.
After changing the webserver from +Apache  to +Nginx the performance in using roundcube is now ok and after the logrotate during midnight I had no sync problems any more with my mobile.
Power consumption is below 3W so it costs only about 7€ per year (0,60€ per month) which is really cheap. Ok you have to add 1€ per month for the domain if you use +regfish for the domain. 
A few days ago I exported all my contacts hosted on the google server and imported them into Kolab. 
So if you don't like to let google know the phone number from your grandma and so on it's up to you to change this and get your own groupware on your server at your home :-)
BTW you can do a lot of other things with your Raspberry Pi.
Greetz