[gdm] pam: grab cached password from systemd and pass it on



commit 31ed6f2b3f1ab45ae07aad41c13a51ba91fd159d
Author: Ray Strode <rstrode redhat com>
Date:   Mon Aug 15 14:11:01 2016 -0400

    pam: grab cached password from systemd and pass it on
    
    If the user has an encrypted disk then systemd will cache the password
    they type into the keyring. It makes sense to try to use this password
    for automatic login purposes first, since on single user machines,
    the sole user password is likely to match the disk password.
    
    Of course if it doesn't work we'll fall back to the old way of doing
    automatic login without a password (and then the user will have to
    manualy enter if they need to for gnome-keyring or whatever)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769950

 configure.ac                       |    8 ++++++++
 data/pam-arch/gdm-autologin.pam    |    3 +++
 data/pam-exherbo/gdm-autologin.pam |    8 +++-----
 data/pam-lfs/gdm-autologin.pam     |    3 +++
 data/pam-redhat/gdm-autologin.pam  |    7 +++++--
 pam_gdm/Makefile.am                |    2 ++
 pam_gdm/pam_gdm.c                  |   29 +++++++++++++++++++++++++++++
 7 files changed, 53 insertions(+), 7 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index cb3a376..ac6afc5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -522,6 +522,14 @@ if test "x$have_pam" = "xyes"; then
        )
 fi
 
+AC_CHECK_LIB(keyutils, keyctl_read, [
+        AC_DEFINE(HAVE_KEYUTILS, 1, [Define if have keyutils])
+        KEYUTILS_LIBS="-lkeyutils"
+        KEYUTILS_CFLAGS=""
+])
+AC_SUBST(KEYUTILS_LIBS)
+AC_SUBST(KEYUTILS_CFLAGS)
+
 dnl Check if we can use the setpenv function to add specialvariable
 dnl to the environment (such as the /etc/environment file under AIX)
 AC_LINK_IFELSE([
diff --git a/data/pam-arch/gdm-autologin.pam b/data/pam-arch/gdm-autologin.pam
index 9f45c65..99b1420 100644
--- a/data/pam-arch/gdm-autologin.pam
+++ b/data/pam-arch/gdm-autologin.pam
@@ -1,5 +1,7 @@
 auth     requisite pam_nologin.so
 auth     required  pam_env.so
+auth     optional  pam_gdm.so
+auth     optional  pam_gnome_keyring.so
 auth     optional  pam_permit.so
 
 account  include   system-local-login
@@ -8,3 +10,4 @@ password include   system-local-login
 
 session  optional  pam_keyinit.so force revoke
 session  include   system-local-login
+session  optional  pam_gnome_keyring.so auto_start
diff --git a/data/pam-exherbo/gdm-autologin.pam b/data/pam-exherbo/gdm-autologin.pam
index 71556e8..afde048 100644
--- a/data/pam-exherbo/gdm-autologin.pam
+++ b/data/pam-exherbo/gdm-autologin.pam
@@ -2,11 +2,9 @@
 # except for the authentication method, which is:
 # always permit login
 
-auth        required    pam_env.so
-auth        required    pam_tally.so file=/var/log/faillog onerr=succeed
-auth        required    pam_shells.so
-auth        required    pam_nologin.so
-auth        required    pam_permit.so
+auth        optional    pam_gdm.so
+auth        substack    system-local-login
+auth        sufficient  pam_permit.so
 -auth       optional    pam_gnome_keyring.so
 
 account     include     system-local-login
diff --git a/data/pam-lfs/gdm-autologin.pam b/data/pam-lfs/gdm-autologin.pam
index 13ac13a..953d47e 100644
--- a/data/pam-lfs/gdm-autologin.pam
+++ b/data/pam-lfs/gdm-autologin.pam
@@ -4,6 +4,8 @@ auth     requisite      pam_nologin.so
 auth     required       pam_env.so
 
 auth     required       pam_succeed_if.so uid >= 1000 quiet
+auth     optional       pam_gdm.so
+auth     optional       pam_gnome_keyring.so
 auth     required       pam_permit.so
 
 account  include        system-account
@@ -12,5 +14,6 @@ password include        system-password
 session  optional       pam_keyinit.so revoke
 session  required       pam_limits.so
 session  include        system-session
+session  optional       pam_gnome_keyring.so auto_start
 
 # End /etc/pam.d/gdm-autologin
diff --git a/data/pam-redhat/gdm-autologin.pam b/data/pam-redhat/gdm-autologin.pam
index 96fcfe3..c2efea8 100644
--- a/data/pam-redhat/gdm-autologin.pam
+++ b/data/pam-redhat/gdm-autologin.pam
@@ -1,6 +1,8 @@
  #%PAM-1.0
-auth       required    pam_env.so
-auth       required    pam_permit.so
+auth       optional    pam_gdm.so
+auth       substack    password-auth
+auth       optional    pam_gnome_keyring.so
+auth       sufficient  pam_permit.so
 auth       include     postlogin
 account    required    pam_nologin.so
 account    include     system-auth
@@ -12,4 +14,5 @@ session    required    pam_selinux.so open
 session    optional    pam_keyinit.so force revoke
 session    required    pam_namespace.so
 session    include     system-auth
+session    optional    pam_gnome_keyring.so auto_start
 session    include     postlogin
diff --git a/pam_gdm/Makefile.am b/pam_gdm/Makefile.am
index 5ea69d7..61d672b 100644
--- a/pam_gdm/Makefile.am
+++ b/pam_gdm/Makefile.am
@@ -15,6 +15,7 @@ pam_gdm_la_SOURCES = \
        $(END_OF_LIST)
 
 pam_gdm_la_CFLAGS = \
+       $(KEYUTILS_CFLAGS) \
        $(PAM_CFLAGS) \
        $(END_OF_LIST)
 
@@ -26,6 +27,7 @@ pam_gdm_la_LDFLAGS = \
        $(END_OF_LIST)
 
 pam_gdm_la_LIBADD = \
+       $(KEYUTILS_LIBS) \
        $(PAM_LIBS) \
        $(END_OF_LIST)
 
diff --git a/pam_gdm/pam_gdm.c b/pam_gdm/pam_gdm.c
index 90a0557..7beb04e 100644
--- a/pam_gdm/pam_gdm.c
+++ b/pam_gdm/pam_gdm.c
@@ -17,18 +17,47 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  */
+#include <config.h>
+
+#include <unistd.h>
+
 #include <security/_pam_macros.h>
 #include <security/pam_ext.h>
 #include <security/pam_misc.h>
 #include <security/pam_modules.h>
 #include <security/pam_modutil.h>
 
+#ifdef HAVE_KEYUTILS
+#include <keyutils.h>
+#endif
+
 int
 pam_sm_authenticate (pam_handle_t  *pamh,
                      int            flags,
                      int            argc,
                      const char   **argv)
 {
+#ifdef HAVE_KEYUTILS
+        int r;
+        void *cached_password = NULL;
+        key_serial_t serial;
+
+        serial = find_key_by_type_and_desc ("user", "cryptsetup", 0);
+        if (serial == 0)
+                return PAM_AUTHINFO_UNAVAIL;
+
+        r = keyctl_read_alloc (serial, &cached_password);
+        if (r < 0)
+                return PAM_AUTHINFO_UNAVAIL;
+
+        r = pam_set_item (pamh, PAM_AUTHTOK, cached_password);
+
+        free (cached_password);
+
+        if (r < 0)
+                return PAM_AUTH_ERR;
+#endif
+
         return PAM_SUCCESS;
 }
 


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