kohsuke / libpam4j

libpam4j
http://libpam4j.kohsuke.org/
MIT License
44 stars 47 forks source link

libpam4j authenticate() fails on centos 8 with org.jvnet.libpam.PAMException: pam_acct_mgmt failed : Authentication failure #25

Closed jamshid closed 4 years ago

jamshid commented 4 years ago

The libpam4j authenticate() function does not seem to work on the recently released CentOS/RHEL8, at least in a docker container.

See below to reproduce. Maybe some PAM configuration requires changes or something needs to be installed for the PAM functionality used by libpam4j to work on centos 8?

/**
 * This simple test program does not work on centos:8, at least in a docker container.
 * It has been working on centos:6 and centos:7.6.1810 Any idea what changed in centos
 * maybe some configuration is needed to enable something libpam4 relied on?
 *
 # SETUP:
 * Download libpam4j and JNA jars:
 * http://mvnrepository.com/artifact/org.kohsuke/libpam4j
 * https://github.com/twall/jna
 * $ docker run -ti centos:8 bash
   yum install -y passwd # already installed on centos:7.6.1810
   yum install -y java-11-openjdk-devel passwd # same behavior with java-8, 
   curl -fLO https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.4.0/jna-5.4.0.jar  # this newer version didn't help
   curl -fLO https://repo1.maven.org/maven2/net/java/dev/jna/jna/4.5.2/jna-4.5.2.jar
   curl -fLO https://repo1.maven.org/maven2/org/kohsuke/libpam4j/1.11/libpam4j-1.11.jar
   useradd -p password gw-john  # -p does not seem to work
   passwd gw-john # enter "password" twice
 * BUILD: 
   javac -classpath ./jna-4.5.2.jar:./libpam4j-1.11.jar:. PamHello.java
 * RUN:   
   java -classpath ./jna-4.5.2.jar:./libpam4j-1.11.jar:. PamHello gw-john password
 * ERROR on centos8:
Exception: org.jvnet.libpam.PAMException: pam_acct_mgmt failed : Authentication failure
org.jvnet.libpam.PAMException: pam_acct_mgmt failed : Authentication failure
    at org.jvnet.libpam.PAM.check(PAM.java:110)
    at org.jvnet.libpam.PAM.authenticate(PAM.java:131)
    at PamHello.main(PamHello.java:40)
 */
import org.jvnet.libpam.PAM;
import org.jvnet.libpam.UnixUser;
public class PamHello {
    public static void main(String[] argv) {
        if (argv.length != 2) {
            System.out.println("Run: 'PamHello username password' to test libpam4j authentication: " + argv.length);
            System.exit(1);
        }
        try {
            PAM pam = new PAM("login");
            UnixUser u = pam.authenticate(argv[0], argv[1]);
            System.out.println("User " + u.getUserName() + " " + u.getUID() + " " + u.getGID() + " " + u.getDir() + " " + u.getGecos() + " " + u.getShell() + " in " + u.getGroups());
        } catch (Exception e) {
            System.out.println("Exception: " + e);
            e.printStackTrace();
            System.exit(1);
        }
        System.exit(0);
    }
}
jamshid commented 4 years ago

There are a few differences between 7 and 8 in the files under /etc/pam.d/ but they don't seem to affect this exception.

I looked for PAM-related changes in RHEL 8, not sure if this is related. https://www.simplylinuxfaq.com/p/major-differences-between-rhel-8-and-7.html

The securetty PAM module has been disabled by default and the '/etc/securetty' file has been removed from RHEL8.

jamshid commented 4 years ago

Closing this as it turns out the problem is a bug or quirk in the official centos:8 image. It contains a file /var/run/nologin that somehow breaks PAM authentication. Just remove the file in your Dockerfile.

FROM centos:8
...
# Fix centos:8 image bug/quirk that breaks PAM authentication: https://github.com/kohsuke/libpam4j/issues/25
RUN rm -f /var/run/nologin
...

The above java program succeeds once the file is gone. Will try to followup here if it's a bug in the image: https://github.com/CentOS/CentOS-Dockerfiles/issues/173