Valid HTML 4.01 Transitional
Personal Information Manager Software

Installing Citadel: Nitty Gritty

James F. Carter <>, 2011-01-30

This is the unexpurgated record of what I did to install Citadel, kept for historical interest. There are also some notes from evaluating it.

According to Citadel's FAQ, it has these key points:

Citadel dependencies:

Required Dependencies

Optional Dependencies

Citadel Packages

Total download size 2.7Mb compressed.

Citadel packages and libSieve were downloaded and built. Compilation was on Jacinth (AMD Geode at 500MHz and with other work to do) and hence was rather slow. Compilation notes:


The directory is named libsieve-2.2.7 (lower case). --prefix=/usr/local [default]. There are no further optional features. ./configure was uneventful. Compilation took 6 minutes, only trivial warnings. Disc space to build: 6.5Mb. Installed size: 0.46Mb. Installs:


--prefix=/usr/local [default]. There are no further optional features. ./configure took 2 mins. Compilation took 4 mins, no or trivial warnings. Disc space to build: 4.7Mb. Installed size: 0.31Mb. Installs /usr/local/lib/ You need to run ldconfig after installing this library, otherwise the Citadel programs, specifically /usr/local/citadel/setup, will not be able to find it.

citadel (server)

Citadel will compile a program called setup which will ask these questions and emit configuration material:

Citadel provides these services with the indicated default port numbers:

Choice of home directory: Experience shows it's best to not tempt fate: use the default of /usr/local/citadel. However, this is going to be a royal pain for configuration management, so after trying and messing up some alternatives I just made a symlink from /usr/local/citadel to /var/lib/citadel and let the programs go in the volatile data area. In reality only the database is really volatile, and the docs show how to configure Berkeley DB to put the files elsewhere, so the symlink could point to a partition for nonshared software, and only the database would be in /var/libcitadel.

These build-time (configure) options are available:

These build dependencies had to be found and added:

The final configure parameters are --with-pam --with-ssl=/usr/lib/ . Took 1.5 mins. Compilation took 5 mins, trivial warnings. Disc space to build: 13.2Mb. Program was installed in /usr/local/citadel, total space 6.8Mb.

In the likely case that you've enabled PAM, you need to edit /etc/pam.d/citadel because it's it's for a Red Hat distro at least three versions back if not more. This is what I'm using; of course the key here is what's in common-auth and common-account. These do the standard authentication and account setup which are done by most PAM-using services, which for most people means, but for me means (Kerberos). Citadel is not able to change a password on the host system, and does not create a real session, so these phases are turned into stubs.

auth include common-auth
account include common-account
password required
session required

The final step will be to run /usr/local/citadel/setup . See answers at the beginning of this section. Gotcha: if you want to put the data in a dir other than /usr/local/citadel, you need to specify -h$dirname to setup, not just to the server.

When Citadel has competing ports, it tries once a second and syslogs an extremely verbose message at level alert, which at least on my system is blasted to every logged-in user, greatly complicating fixing it. Problems with ports: 25 (smtp), 5222 (xmpp),

It creates an old-style script in /etc/init.d/citadel which will have to be hand-edited for LSB compliance and to use startproc, killproc and checkproc. [Done.]

Server's command line options (defaults are shown):

There is a command line client called /usr/local/citadel/citadel. Need to try it out.

Citadel logs a lot of stuff at debug level. Need to prune this. Once a minute it logs that it created a SMTP send thread (etc.) -x5 is not enough. -x4 cuts out most of the crap. Do we really need to know that chmod data/cdb.06, 0600 returned 0, on every logged-in console?

How to put the database in /var: See the Citadel FAQ for How may I improve performance by placing the databases and/or database logs on separate disk subsystems? You only want to move the data and logs dirs. Then create /usr/local/citadel/data/DB_CONFIG which says:

set_data_dir /var/lib/citadel/data
set_lg_dir /var/lib/citadel/data

This is the component which provides the webserver. By default it binds to port 2000. We will use 2080, the FlexLM assigned port, and/or 2443 (PowerClient Central Storage Facility). After building, you need to run /usr/local/webcit/setup (which used to muck with inittab, but doesn't do this any more.)

Configure and build:

Command line options for webcit:

For SSL it will need ./keys/citadel.{key,csr,cer}. These should be set up as symlinks to the corresponding files in /etc/ssl. I don't know why it cares about the CSR, but the docs say it wants to see it. Command to make the CSR (if you didn't save it when getting your certificate signed):
openssl req -new -key /etc/ssl/private/host.key \
-out /etc/ssl/hostcerts/host.csr

For web integration, Webcit has to be on a separate port from Apache; we're using 2080 and/or 2443. If the clients absolutely have to come in on 80 or 443, use Apache's mod_proxy and tell Apache to act as a proxy for the Webcit server. README.txt tells how to do that.

Initial Login to Citadel

Using the citadel command.

Problem #1: can't open citadel.rc. Forgot the symlink. Made, fixed.

Problem #2: can't find 'hello' in /usr/local/citadel/messages/ or /usr/local/citadel/help/ -- similar problem. The symlink issues have to be improved (and were, later).

Problem #3: Give password, Kerberos fails, decrypt integrity check failed. It writes the password on FD 30 which is a pipe attached to... inode 716350. This should be its own password checker daemon. Yes it is. It does the PAM thing including

Tried Webcit/2080 -- it let me on. Conclusion: the password was not read correctly by citadel UI. GAACK! That's literally true! strace shows that it read 19 bytes out of 26. Needs bug report and patch. [Done, works.]

Webcit/2443 did not start; why? It's a baleful interaction between startproc and the other instance on 2080. Maybe we don't want 2080 anyway because the user has to log in! Or startproc needs -i. [Fixed by not starting the instance on 2080.]

Using webcit, I log in as jimc, and look all over for the Administration tab and its Edit site-wide configuration menu item, but I don't see either. See support request below (reply didn't help).

I sabotaged authentication by changing /etc/pam.d/citadel so every category has just sufficient (and restarted Citadel). It let me on, at level 4 (ordinary user) which is why I don't have an Administration tab. Use the source, Luke! In ./user_ops.c do_login() if (!strcasecmp(CC->user.fullname, config.c_sysadm)) { set to AxAideU } Or do this if using host auth and root logs in, identified by uid == 0. That's the fullname (GECOS). So you have to specify that, not the loginID, to setup. Now I can get in with Aide privileges (level 6).

Hacking Citadel: Text Client Password Length

Goals of hacking: (A) Extend the max password length of the text client; (B) figure out why it won't let me on as an Aide (sysop); (C) squeeze in SASL; (D) make it stop logging its chmod outcomes at level emerg, i.e. to every logged in user.

This is in textclient/citadel.c . Main program, char password[SIZ]; ./sysconfig.h: #define SIZ 4096. That's not the problem. Further on it says: newprompt("\rPlease enter your password: ", password, -19); Got to raise that -19. What does it mean? This is in commands.c . Calls ctdl_getline(str, len); defined in the same file. Negative length means don't echo (for passwords). Why do they use ^W rather than ^U to erase the line? OK, changed length to -(SIZ-1) from -19.

Confirmed, it's fixed. Patch was posted.

Hacking Citadel: Shut Up Chown and Chmod Log Messages

This is in database.c:430. It calls CtdlLogPrintf(9, "format", args). That function is declared in sysdep_decls.h and defined in sysdep.c. The first arg is a log level of type enum LogLevel. I can't find the definition of this enum, and it's passed as an int to vsyslog() which is a backend to syslog(). Log level 9 is not defined in /usr/include/sys/syslog.h; it ranges from 0 to 7 and there's a bitmask implying that only the lower 3 bits are considered. (7&9) == 1 which is LOG_ALERT, which on my system is barfed to every user's screen. Changing the 9 to CTDL_DEBUG (which is 7). I can't find the actual definition of CTDL_DEBUG.

The same issue occurs in several other files and the messages also appear annoyingly. I'm mapping 0 and 9 to CTDL_DEBUG, 1 to CTDL_ALERT.

Confirmed, the most noticeable and annoying ones are gone. Patch was posted.

Hacking Citadel: The XMPP Server Lacks SSL

The relevant source file is ./modules/xmpp/serv_xmpp.c . It has XMPP support but the code to announce STARTTLS is commented out. The developer (Ignatius) says there's an (unspecified) problem with it at the moment.

Turning it back on: on initial connection the client (Pidgin) complains that the Common Name in the cert is *. If you tell Pidgin to ignore this error, it connects and actually uses SSL. Fingerprint = 87:b6:3f:c1:75:a0:0f:34:7c:a3:d9:1c:5f:a4:3a:0e:59:f1:87:ba

Testing using OpenSSL utility:
openssl s_client -CApath /etc/ssl/certs -connect -starttls xmpp
Starttls protocol support is for smtp, pop3, imap or ftp (and evidently xmpp has been added.) Send Q to shut down the connection.

Evidently -starttls xmpp was acceptable, and evidently it's really sending in this bogus certificate: depth=0 /O=CFT Citadel/OU=Citadel server/CN=* (self signed certificate). When I reinstalled Citadel I forgot to reinstall the /usr/local/citadel/keys/citadel.* symlinks! Let's fix that: take both Pidgin instances offline, stop citserver, fix the certs, restart everything. Now there is no complaint when I connect. It all seems to work. Here's the message I posted:

Subject: Re: XMPP TLS upgrade

Thu Jan 27 2011 10:40:43 AM EST from IGnatius T Foobar @ Uncensored Subject: Re: XMPP TLS upgrade

Our XMPP service has TLS disabled because it doesn't seem to work when we enable it. If you can figure out what's wrong and submit a patch that makes it work reliably, you will be hailed as a conquering hero and tickertape parades will be given in your honor.

Well, I can't really say I conquered anything, but I modified ./modules/xmpp/serv_xmpp.c line 147 in xmpp_stream_start(), changing to just "#ifdef HAVE_OPENSSL" (letting it announce STARTTLS as a stream feature). TLS works for me. I verified that it's really not sending plaintext (with tcpdump) and checked that the connection was sane (using openssl s_client -connect -starttls xmpp) (I'm using an alternate port for testing). It seems to work normally. I can do IM communication between two client instances. The only incorrect behavior I see is presence: if one partner sets "do not disturb" or "extended away" he remains "available" in the other partner's buddy list. But there's enough oddness on the client side (could be a problem between keyboard and chair) that it's way too early to even look at server issues on this. And in any case transport (TLS) is irrelevant for this issue.

I'm going to put this sucker into production! I'll report if anything weird happens, particularly related to TLS.

For reference, I'm using Citadel 7.85, Pidgin and libpurple 7.2.9, Evidently libpurple has some SSL/TLS library statically linked (hiss, boo!) so I can't report what they're using.

One nasty "non-working" behavior I hit was this: When I reinstalled Citadel I forgot to redo the symlinks in /usr/local/citadel/keys, and it silently created a self-signed cert with a Common Name of "*", which is rejected by any sane TLS client since "*" is unequal to the alphabetic hostname used to connect, typically the FQDN of the server (but sometimes a CNAME, fully qualified). It would be nice if the FQDN could be deduced for creating the self-signed cert, but that takes a little work. Better to remember to install your proper cert and key.

Reply from dothebart: committed to source codebase.

Hacking Citadel: Making Some Nice Message Forms

List of forms that I hacked, in /usr/local/citadel/messages; the original messages are in $source/messages and help :

Support Messages

For support, create an account on (I'm user jimcuclamath, standard password), and post in the Citadel Support room. It has a year's worth of messages, 1769 of them. Jump to the last page of the room.

Evaluating Citadel

Now that I have Citadel running, what can I do with it?


The Webcit interface is reasonable for adding hour-bounded events, date range events, and recurring events on specific weekdays. Adding attendees: the Citadel list is of users who have logged in before. Global Address Book: see below for how to edit it. I tried to use my personal contact list to add an outside attendee, but for both it and the Global Contact List, the pop-up list showed \008 and no contacts (a bug).

Now here's a point, does it have shared calendars? I don't see the controls for that. But the docs say you can do that. Dothbert says: create a public room on a public floor and make it type calendar in the dropdown list when creating.

This works, and individual users can see the shared calendar. It would be nece if there were a merged calendar view, though.

How to set up Lightning in Thunderbird (probably Firefox is similar). This HOWTO from Citadel support recommends using SyncKolab to talk IMAP to Citadel.

Alternatively, let's try to do the calendar natively. Begin by de-installing SyncKolab, just to keep things simple. I'm following the HOWTO for iCal.


The form for adding a contact is reasonably easy to use. Two fields I would appreciate adding are what the person's relation is to me (e.g. dentist), and generic notes about the person. Make it into a real Farley file.

Lightning does not do anything for contacts, but there's got to be an add-on which does.

To add to the Global Address Book: Rooms tab, find Global Address Book and go to it, and use the Add New Contact menubar item. or click on an item to view it, then hit Edit.


Reasonable form to add a task, with an area for generic notes. It has categories. Haven't found how it orders dated tasks, or what happens when you mark a task as completed.

I found a bug! If you select a particular category to be shown, the heading vanishes! Obiously each table row has CSS attribute display:hidden (or normal) and the Javascript executor for the category dropdown list sets the display attribute to hidden in items other than the desired class, including the stuffing of the header but not the header itself or the menubar and its stuffing.


I didn't do much with notes. They use the metaphor of Post-It® notes; they're yellow, 30x9 Monospace bytes in size (resizeable).


How do I export an event or an entire calendar, contact, etc. as a file?

Client support

How do I get vCard-type access to Citadel calendars and contacts? Specifically from a client on another host, e.g. Android or iPhone?

Browser Support

Webcit's Javascript was tested on these browsers:

GroupDAV For Generic Clients

Citadel FAQ's answer: For KOrganizer or other client software, configure the groupware server to be of type GroupDAV (or is equivalent for this purpose). The URLs should be http://hostname/groupdav/ for your own PIM objects, and http://hostname/freebusy/ for other users' free-busy indications.

What is GroupDAV software? Results from Wikipedia: