Blob Blame History Raw
From 16cebfeb30a8bd7c7dc269190a054c25b0f8d044 Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
Date: Tue, 15 Sep 2020 15:54:10 +0200
Subject: [PATCH 1/2] pam_motd: filter motd by user and group

modules/pam_motd/pam_motd.c: filter motd by user and group owning the
proper files. This is achieved by changing the ids of the process
reading the files from root to the target user.

Resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=1861640
---
 modules/pam_motd/pam_motd.c | 97 ++++++++++++++++++++++++++++---------
 1 file changed, 75 insertions(+), 22 deletions(-)

diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
index 46f4fe61..a4fd0e59 100644
--- a/modules/pam_motd/pam_motd.c
+++ b/modules/pam_motd/pam_motd.c
@@ -282,6 +282,72 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
     _pam_drop(dirscans);
 }
 
+static int drop_privileges(pam_handle_t *pamh, struct pam_modutil_privs *privs)
+{
+    struct passwd *pw;
+    const char *username;
+    int retval;
+
+    retval = pam_get_user(pamh, &username, "key user");
+
+    if (retval == PAM_SUCCESS) {
+        pw = pam_modutil_getpwnam (pamh, username);
+    } else {
+        return PAM_SESSION_ERR;
+    }
+
+    if (pw == NULL || pam_modutil_drop_priv(pamh, privs, pw)) {
+        return PAM_SESSION_ERR;
+    }
+
+    return PAM_SUCCESS;
+}
+
+static int try_to_display(pam_handle_t *pamh, char **motd_path_split,
+                          unsigned int num_motd_paths,
+                          char **motd_dir_path_split,
+                          unsigned int num_motd_dir_paths, int report_missing)
+{
+    PAM_MODUTIL_DEF_PRIVS(privs);
+
+    if (drop_privileges(pamh, &privs) != PAM_SUCCESS) {
+        pam_syslog(pamh, LOG_ERR, "Unable to drop privileges");
+        return PAM_SESSION_ERR;
+    }
+
+    if (motd_path_split != NULL) {
+        unsigned int i;
+
+        for (i = 0; i < num_motd_paths; i++) {
+            int fd = open(motd_path_split[i], O_RDONLY, 0);
+
+            if (fd >= 0) {
+                try_to_display_fd(pamh, fd);
+                close(fd);
+
+                /* We found and displayed a file,
+                    * move onto next filename.
+                    */
+                break;
+            }
+        }
+    }
+
+    if (motd_dir_path_split != NULL) {
+        try_to_display_directories_with_overrides(pamh,
+                                                    motd_dir_path_split,
+                                                    num_motd_dir_paths,
+                                                    report_missing);
+    }
+
+    if (pam_modutil_regain_priv(pamh, &privs)) {
+        pam_syslog(pamh, LOG_ERR, "Unable to regain privileges");
+        return PAM_SESSION_ERR;
+    }
+
+    return PAM_SUCCESS;
+}
+
 int pam_sm_open_session(pam_handle_t *pamh, int flags,
 			int argc, const char **argv)
 {
@@ -358,25 +424,9 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
 	}
     }
 
-    if (motd_path_split != NULL) {
-	unsigned int i;
-
-	for (i = 0; i < num_motd_paths; i++) {
-	    int fd = open(motd_path_split[i], O_RDONLY, 0);
-
-	    if (fd >= 0) {
-		try_to_display_fd(pamh, fd);
-		close(fd);
-
-		/* We found and displayed a file, move onto next filename. */
-		break;
-	    }
-	}
-    }
-
-    if (motd_dir_path_split != NULL)
-	try_to_display_directories_with_overrides(pamh, motd_dir_path_split,
-		num_motd_dir_paths, report_missing);
+    retval = try_to_display(pamh, motd_path_split, num_motd_paths,
+                            motd_dir_path_split, num_motd_dir_paths,
+                            report_missing);
 
   out:
     _pam_drop(motd_path_copy);
@@ -384,9 +434,12 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
     _pam_drop(motd_dir_path_copy);
     _pam_drop(motd_dir_path_split);
 
-    retval = pam_putenv(pamh, "MOTD_SHOWN=pam");
-
-    return retval == PAM_SUCCESS ? PAM_IGNORE : retval;
+    if (retval == PAM_SUCCESS) {
+        retval = pam_putenv(pamh, "MOTD_SHOWN=pam");
+        return retval == PAM_SUCCESS ? PAM_IGNORE : retval;
+    } else {
+        return retval;
+    }
 }
 
 /* end of module definition */
-- 
2.26.2


From ad8b6feaf8ea989368676acaea905998a807986e Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
Date: Wed, 14 Oct 2020 11:30:00 +0200
Subject: [PATCH 2/2] pam_motd: document file filtering

modules/pam_motd/pam_motd.8.xml: document file filtering of motd
messages.
NEWS: annotate change.
---
 NEWS                            | 3 +++
 modules/pam_motd/pam_motd.8.xml | 5 +++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/NEWS b/NEWS
index e8c0de87..c3b338e2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
 Linux-PAM NEWS -- history of user-visible changes.
 
+Release 1.5.0
+* pam_motd: read motd files with target user credentials skipping unreadable ones.
+
 Release 1.4.0
 * Multiple minor bug fixes and documentation improvements
 * Fixed grammar of messages printed via pam_prompt
diff --git a/modules/pam_motd/pam_motd.8.xml b/modules/pam_motd/pam_motd.8.xml
index b533530b..0afd4c99 100644
--- a/modules/pam_motd/pam_motd.8.xml
+++ b/modules/pam_motd/pam_motd.8.xml
@@ -64,8 +64,9 @@
       override files with the same name in <filename>/usr/lib/motd.d/</filename>.
     </para>
     <para>
-      Files the in the directories listed above are displayed in
-      lexicographic order by name.
+      Files in the directories listed above are displayed in lexicographic
+      order by name. Moreover, the files are filtered by reading them with the
+      credentials of the target user authenticating on the system.
     </para>
     <para>
       To silence a message,
-- 
2.26.2