[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Cyrus-SASL, PAM and NIS on Linux


Yesterday I tried to setup a Cyrus IMAP server on a
Linux system which also is a NIS client and had some
troubles with user authentication.

I spent the whole sunday on this problem, and I think I found
the solution. As I imagine there might be others in a similar
situation, I would like to share my findings with you.

Executive summary: Authenticating Cyrus IMAPD users against
a NIS server using PAM works on Linux, but might require a
small modification of the NIS maps Makefile on the NIS server
in case it uses shadow passwords.

The problem & solution in full detail:

The situation is as follows:

*) I have a mailserver in a local Linux network, which runs
   sendmail, a SMTP virus scanner and should run the Cyrus 
   IMAPD for about 50 users in the future.
   I'm using cyrus-imapd-1.6.24 and cyrus-sasl-1.5.24

*) In the same network there is a Samba fileserver which
   also has the standard Linux account database, consisting
   of the usual /etc/shadow and /etc/passwd files. This 
   fileserver is also the NIS master (it has two NIS slaves
   for redundancy in the same network)

*) All systems use PAM for authentication (pam-0.73), this did 
   work fine in the past for serives like SSH, telnet and even
   Qpopper (which was used for mail access in the past and 
   should no be replaced by Cyrus IMAPD)

Initially I configured the IMAP server as described in
the various documents. (I also have "Managing IMAP" from
O'Reilly, but this doesn't cover the NIS/PAM situation)

The Cyrus configuration file looks like this:

# /etc/imapd.conf
configdirectory: /var/imap
partition-default: /var/spool/imap
admins: cyrus root
srvtab: /var/imap/srvtab
allowanonymouslogin: no
sasl_pwcheck_method: PAM
pwcheck_method: PAM
# end of file

The SASL library is compiled with the --with-pam option

There is a PAM configuration file stored in /etc/pam.d/imap
which essentially looks as follows:

# /etc/pam.d/imap
auth            required        pam_pwdb.so try_first_pass
account         required        pam_pwdb.so
# end of file

pam_pwdb uses the pwdb library. There is a configfile for
that, too, which looks like this:

# /etc/pwdb.conf

# end of file

The Cyrus IMAPD is started by the inetd program. This is 
configured in /etc/inetd.conf:

imap stream tcp nowait cyrus /usr/libexec/cyrus/bin/imapd imapd

User "cyrus" has UID 18 and is registered in the local
/etc/passwd file on the mailserver (NIS only serves
accounts with UID >= 100)

Now, this setup gave me lots of headaches. The IMAP server
just wouldn't let me log in as authentication always failed
in the PAM module (according to the logfiles)

I tried to debug this with strace, and finally found the problem:

On the NIS server, I had the NIS Makefile (/var/yp/Makefile)
set up with "MERGE_PASSWD=false"
That way, the NIS map "passwd" did not contain the encrypted
passwords, which are stored in the "shadow" map. But even there,
the NIS server only hands out the encrypted passwords if you connect 
it from a port number below 1024, where only "root" has access 
to. As soon as I call "ypcat shadow" as normal user, I only get
"x" in the passwd fields of the shadow map!
This of course is a security feature, as "ypcat" can be called
by everyone on the system and would make the shadow file setup
completely useless otherwise.
The problem now seems to be that the PAM pwdb library doesn't have
a separate SUID "root" program to check the NIS passwords. It only
uses this for local authentication agains /etc/shadow!
(At least I get this impression looking at the output of strace)

So the Cyrus IMAPD calls the SASL functions, which in turn call
the PAM functions, which in turn call the pwdb library, which
then directly calls the glibc YP functions as user "cyrus".
But that way it never gets the real encrypted passwords from the
NIS server!

The quick solution now is to set "MERGE_PASSWD=true" in the
/var/yp/Makefile on the NIS server and compile all the maps.
So the "passwd" NIS map now contains all the encrypted passwords 
and PAM is happy (I think one could also tweak the /etc/ypserv.conf 
file to get the same effect, but I haven't tried this).

This is of course a security problem, as now every normal user can 
obtain the encrypted passwords just by calling "ypcat passwd", just 
like on a Unix system without shadow passwords...

IMHO, the real solution would be to have PAM use an external SUID 
"root" program to connect to the NIS server, too, not just
for reading the local "/etc/shadow" file.

I hope my description is not too confusing for you. It's a quite
complicated mechanism, and it fails at a very low layer...

What do you PAM maintainers think about this? The situation
I found shouldn't be to uncommon so it would be good to find 
a clean solution (Due to the security implications I call 
"MERGE_PASSWD=true" rather a hack than a clean solution).
Is it possible to have an external SUID root program to be
called by the pwdb library in case of NIS autentication?
Would this make sense? What do you think?

Any information is appreciated!


Andreas Haumer

Andreas Haumer                     | mailto:andreas@xss.co.at
*x Software + Systeme              | http://www.xss.co.at/
Karmarschgasse 51/2/20             | Tel: +43-1-6060114-0
A-1100 Vienna, Austria             | Fax: +43-1-6060114-71

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] []