Revisiting Linux PAM: does authentication really require root access to /etc/shadow?

2025-09-05 20:53:00

Consider this part 2 of a two part series. Here is part 1.

While researching the use of PAM for authentication I was surprised: I thought the PAM API enabled any application to use the local Linux authentication files in an easy and safe way.

Taken literally that statement is true. But it lacks one detail: it doesn't mention the access rights needed by the application!

To my brain "any application" literally meant every application running on Linux. I hadn't considered limitations! I'd thought PAM was an active mediator, but instead I'm now reminded that it's a set of programming libraries. There is no PAM service which performs authentication for you, you have to do it yourself. 

PAM and Apache web server

Because I really can't work with Java, I thought I'd find an example that's closer to my understanding: the Apache web server.

There is more than one Apache module to authenticate against PAM, the most popular being mod_authnz_pam.

I started with a walkthrough like this article on Siberoloji. It's outdated and I needed to make a lot of changes to the workflow (which I will turn into a lab for my Linux+ class!). 

I soon had Ubuntu running Apache, with /var/www/html/private being blocked off by PAM authentication. A curl without --basic immediately leads to a 401 Unauthorized (as expected). Trying the curl with basic authentication and my username and a wrong password also gave the 401. Good. 

But when I tried my username with the real password, I also wasn't let in:

     unix_chkpwd[4159]: check pass; user unknown
unix_chkpwd[4159]: password check failed for user (tess)
apache2[4076]: pam_unix(apache2:auth): authentication failure; logname= uid=33 euid=33 tty= ruser= rhost=127.0.0.1 user=tess

Most assuredly my user is not unknown! It's right there in /etc/shadow

Looking at the code and the documentation for the Apache module, I see that it uses a compiled C binary, unix_chkpwd. The documentation for this tool clearly states that it must be run as the root (uid=0) user account, otherwise you cannot authentication other users than yourself. 

On systems with SELinux, you even need to set an additional boolean to allow the webserver to work with PAM: 

     setsebool -P httpd_mod_auth_pam 1

It still wasn't clicking for me: surely you should be able to use PAM and unix_chkpwd without root access, right?!

And that's when I found a blog post that I had written in October of 2020. It was literally the second hit in Google and Ecosia! I had already done this whole research four years ago! It was also discussed on RedHat support.

As a test, I modified the Apache user account to be in the shadow group:

     sudo usermod -aG shadow www-data

And presto, now I can authenticate with my real username and password.

One final test: the LibPAM proof of concept

I thought I'd give it one final shot! I turned to the PAM developer documentation, which has a very simple demo program to perform a username/password check.

To build the application on Ubuntu, I installed the libpam0g-dev package via APT. I then compiled it by running:

     gcc pamtest.c -lpam -lpam_misc -o pamtest.o

If I run pamtest.o without any parameters, it defaults to user "nobody". And that gives results we've seen before:

     unix_chkpwd[83004]: check pass; user unknown
unix_chkpwd[83004]: password check failed for user (nobody)
pamtest.o[83002]: pam_unix(check_user:auth): authentication failure; logname=tess uid=1000 euid=1000 tty= ruser= rhost= user=nobody

If I run pamtest.o with my username as the argument, it works perfectly.

If I run "sudo ./pamtest.o www-data" and I give it that user's password, it also works. 

Conclusion

Yes, Tess. PAM authentication really does need privileged read access to /etc/shadow. You can't escape it. 

See you in four years, when you've forgotten this again. ;)

Lab exercise: Apache and PAM authentication

I've added a lab exercise to day 14 of my Linux+ class. It walks you through setting up a protected website which uses the local Unix user database for authentication.

The PDF is here on Github, the lab starts on slide number 48.


kilala.nl tags: , ,

View or add comments (curr. 0)