[rt-users] Funky exim rules and kerberos integration with RT2

Matt Johnson mwj99 at doc.ic.ac.uk
Wed Oct 10 16:40:21 EDT 2001


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I've been looking at RT2 (with a view to possibly replacing our current
request-tracking system), and testing to see what it can do.

Overall, I am *very* impressed. Big kudos to Jesse for an excellent
system. :)

During the setup of the test machine, I had to do some interesting
configuration to get RT2 to "play nice" with the rest of our Linux
setup -- here's the results, just for people's reference.

1) Exim configuration

RT2 was installed on my desktop machine (i.e. webserver, postgres server
and rt2) for testing. Our desktop systems (and our webservers, as a
matter of fact) are all configured as follows, mailwise:

* Anything outside of our organizational domain (.example.org) or
addressed to <localpart>@example.org, send it straight to our
smarthosts.
* Anything addressed to <localpart>@hostname.example.org should be
rewritten to the form <localpart>@example.org, then forwarded to the
smarthosts.

(This is in order to make command-line `mail` incantations work, e.g.
`mail root` actually reaches system administrators.)

However, this causes problems for RT. I decided to use the rather natty
Exim setup listed in the configuration guide (supporting addresses such
as rt-help+correspond at rt-host).

During this testing phase, I wanted to be able to mail
rt-queue+action at rt-host.example.org and have it handled by RT2, without
it getting clobbered by the rules mentioned above. I also wanted to be
able to mail queue at rt-host... and have it handled as
rt-queue+correspond.

The resulting exim config was complex. :)

The Transport configuration remained identical to that shown in the
Installation docs. However, the directors needed some work. :)

The first director was:

reqtracker_aliases:
  driver = aliasfile
  condition = ${if match{$domain}{^rt\-host\.example\.org}{1}{0}}
  file = /etc/rtaliases
  search_type = lsearch

Which looks at /etc/rtaliases and converts the short queue@ to
rt-queue+correspond. I also included a condition line, in order to
push any mail *not* explicitly addressed to rt-host throught to the next
director.

The next director was:

reqtracker_real:
  driver = smartuser
  condition = ${if and {{match{$domain}{^rt\-host\.example.org}}
                        {match{$local_part_prefix}{^rt\-}}} {1} {0}}
  suffix = +*
  prefix = *-
  new_address = ${quote:${lc:${local_part}}}@${domain}
  transport = reqtracker

(That condition should be one long line.)

This looks very similar to the director listed in the Installation
Guide, but with the important addition of the condition.

Exim's smartuser is greedy and will match anything it can get its grubby
mitts on. Fortunately, we know that none of our usernames contain
hyphens or plus signs, and thus no "real user" can be called
'rt-'something.

Our final director is a redirecting smartuser, with no condition, with a
simple new_address rewrite. (not included, this isn't an exim
programming reference :-))

This setup has the advantage of making sure all aliases we want get
routed to RT2, that all RT's "internal" mail addresses are routed
correctly, and (most importantly) maintains the status quo that
<localpart>@hostname.example.org still gets rewritten and bounced to the
mailhost.

2) Kerberos integration

Our network uses Kerberos5 authentication for users, and it is very
desirable to have a single set of usernames and passwords for access to
all network resources, including RT2. Thanks to Jesse including the
$WebExternalAuth switch, this was made extremely easy -- but for one
snag. :-)

As shipped, RT2 says that although you can delegate authentication to
the webserver, the users must already exist in RT2's user database
before they can access the web interface. This is not desirable for our
purposes -- all users should be able to go to the RT2 site and view the
system, no matter if they have mailed a request or have been manually
created. (The main reason that we're happy to go in this direction is
because of our single authoritative Kerberos setup.)

In order to get Kerberos authentication working, I rebuilt Apache 1.3.20
with mod_auth_kerb
<http://stonecold.unity.ncsu.edu/software/mod_auth_kerb/>, and also with
mod_ssl <http://www.modssl.org>, because we don't like our system
passwords flying in plaintext over the wire. Once mod_auth_kerb is set
up correctly (fairly easy, given the docs), I modified the httpd.conf
thusly:

<VirtualHost x.x.x.x>
DocumentRoot /usr/local/rt2/WebRT/html
ServerName rt-host.example.org
PerlModule Apache::DBI
PerlFreshRestart On
PerlRequire /usr/local/rt2/bin/webmux.pl
<Location />
 ############
 # KERBERISATION
 ############
 AuthType KerberosV5
 AuthName "Kerberos Login"
 KrbAuthRealm EXAMPLE.ORG
 Require valid-user
 ############
 SetHandler perl-script
 PerlHandler RT::Mason
</Location>
</VirtualHost>

(You will obviously want to change the kerberos realm.)

This gets the $ENV{REMOTE_USER} part working, and now setting
$WebExternalAuth high in config.pm will successfully delegate
authentication. However, this doesn't fix the problem of "all users
should be implicitly authorized".

Fixing this is a patch to the autohandler in WebRT/html/, a diff
follows. You will need to modify the @example.org to something suitable
for your setup.

(start of diff)
- --- autohandler-orig	Wed Oct 10 12:48:10 2001
+++ autohandler	Wed Oct 10 14:12:15 2001
@@ -16,9 +16,26 @@
     $session{'CurrentUser'} = RT::CurrentUser->new();
     $session{'CurrentUser'}->Load($user);
     unless ($session{'CurrentUser'}->id() ) {
- -        delete $session{'CurrentUser'};
- -        $m->comp('/Elements/Login', %ARGS, Error=> 'You are not an authorized user');
- -        $m->abort();
+         # Create a new user.
+         my $emailaddress = $user . '@example.org';
+         my ($UserFoundInExternalDatabase, %UserInfo) = RT::LookupExternalUserInfo($emailaddress, $user);
+
+         foreach my $key (keys %UserInfo) {
+             my $value = $UserInfo{$key};
+             print STDERR "$key: $value\n";
+         }
+         my $NewUser = RT::User->new($RT::SystemUser);
+
+         $NewUser->Create(Name => $ENV{'REMOTE_USER'},
+                          EmailAddress => $emailaddress,
+                          RealName => $UserInfo{'RealName'},
+                          Password => undef,
+                          Gecos => $ENV{'REMOTE_USER'},
+                          Privileged => 0,
+                          Comments => 'Autocreated on Kerberos Login to web'
+                         );
+
+         $session{'CurrentUser'}->LoadByEmail($emailaddress);
     }
 }

(end of diff)

I have also written a LookupExternalUserInfo for the local password
database (getpwnam()). You can find it at:

http://www.doc.ic.ac.uk/~mwj99/GetPasswdData.txt

Hope this proves of use to somebody. :)

Regards,
- -- 
Matt Johnson <mwj99 at doc.ic.ac.uk>

"There are two ways to write error-free programs.
But only the third one works."
 - Graf, 'Murphys Computergesetze'
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE7xLI5NHkw5OSqNcERAhF7AJwIDZGbCsN6IwqqByRiqGbchyA+AgCeJ2GD
+63LUkR5NnSmt61ryvNptjs=
=TT9s
-----END PGP SIGNATURE-----





More information about the rt-users mailing list