Patch for Ubuntu bug #399071

Provide a more dynamic MOTD, based on the short-lived update-motd project.

Authors: Dustin Kirkland <kirkland@canonical.com>

Upstream status: not yet submitted

Index: pam.debian/modules/pam_motd/pam_motd.c
===================================================================
--- pam.debian.orig/modules/pam_motd/pam_motd.c
+++ pam.debian/modules/pam_motd/pam_motd.c
@@ -48,14 +48,39 @@
 
 static char default_motd[] = DEFAULT_MOTD;
 
+static void display_file(pam_handle_t *pamh, const char *motd_path)
+{
+    int fd;
+    char *mtmp = NULL;
+    while ((fd = open(motd_path, O_RDONLY, 0)) >= 0) {
+	struct stat st;
+	/* fill in message buffer with contents of motd */
+	if ((fstat(fd, &st) < 0) || !st.st_size || st.st_size > 0x10000)
+	    break;
+	if (!(mtmp = malloc(st.st_size+1)))
+	    break;
+	if (pam_modutil_read(fd, mtmp, st.st_size) != st.st_size)
+	    break;
+	if (mtmp[st.st_size-1] == '\n')
+	    mtmp[st.st_size-1] = '\0';
+	else
+	    mtmp[st.st_size] = '\0';
+	pam_info (pamh, "%s", mtmp);
+	break;
+    }
+    _pam_drop (mtmp);
+    if (fd >= 0)
+	close(fd);
+}
+
 PAM_EXTERN
 int pam_sm_open_session(pam_handle_t *pamh, int flags,
 			int argc, const char **argv)
 {
     int retval = PAM_IGNORE;
-    int fd;
+    int do_update = 1;
     const char *motd_path = NULL;
-    char *mtmp = NULL;
+    struct stat st;
 
     if (flags & PAM_SILENT) {
 	return retval;
@@ -73,6 +98,9 @@
 			   "motd= specification missing argument - ignored");
 	    }
 	}
+	else if (!strcmp(*argv,"noupdate")) {
+		do_update = 0;
+	}
 	else
 	    pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
     }
@@ -80,34 +108,23 @@
     if (motd_path == NULL)
 	motd_path = default_motd;
 
-    while ((fd = open(motd_path, O_RDONLY, 0)) >= 0) {
-	struct stat st;
-
-	/* fill in message buffer with contents of motd */
-	if ((fstat(fd, &st) < 0) || !st.st_size || st.st_size > 0x10000)
-	    break;
-
-	if (!(mtmp = malloc(st.st_size+1)))
-	    break;
-
-	if (pam_modutil_read(fd, mtmp, st.st_size) != st.st_size)
-	    break;
-
-	if (mtmp[st.st_size-1] == '\n')
-	    mtmp[st.st_size-1] = '\0';
-	else
-	    mtmp[st.st_size] = '\0';
-
-	pam_info (pamh, "%s", mtmp);
-	break;
+    /* Run the update-motd dynamic motd scripts, outputting to /run/motd.dynamic.
+       This will be displayed only when calling pam_motd with
+       motd=/run/motd.dynamic; current /etc/pam.d/login and /etc/pam.d/sshd
+       display both this file and /etc/motd. */
+    if (do_update && (stat("/etc/update-motd.d", &st) == 0)
+        && S_ISDIR(st.st_mode))
+    {
+	mode_t old_mask = umask(0022);
+	if (!system("/usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new"))
+	    rename("/run/motd.dynamic.new", "/run/motd.dynamic");
+	umask(old_mask);
     }
 
-    _pam_drop (mtmp);
-
-    if (fd >= 0)
-	close(fd);
+    /* Display the updated motd */
+    display_file(pamh, motd_path);
 
-     return retval;
+    return retval;
 }
 
 
Index: pam.debian/modules/pam_motd/pam_motd.8.xml
===================================================================
--- pam.debian.orig/modules/pam_motd/pam_motd.8.xml
+++ pam.debian/modules/pam_motd/pam_motd.8.xml
@@ -52,6 +52,17 @@
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <option>noupdate</option>
+        </term>
+        <listitem>
+          <para>
+            Don't run the scripts in <filename>/etc/update-motd.d</filename>
+            to refresh the motd file.
+          </para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
Index: pam.debian/modules/pam_motd/pam_motd.8
===================================================================
--- pam.debian.orig/modules/pam_motd/pam_motd.8
+++ pam.debian/modules/pam_motd/pam_motd.8
@@ -45,6 +45,13 @@
 /path/filename
 file is displayed as message of the day\&.
 .RE
+.PP
+\fBnoupdate\fR
+.RS 4
+Don\*(Aqt run the scripts in
+/etc/update\-motd\&.d
+to refresh the motd file\&.
+.RE
 .SH "MODULE TYPES PROVIDED"
 .PP
 Only the
Index: pam.debian/modules/pam_motd/README
===================================================================
--- pam.debian.orig/modules/pam_motd/README
+++ pam.debian/modules/pam_motd/README
@@ -14,6 +14,10 @@
 
     The /path/filename file is displayed as message of the day.
 
+noupdate
+
+    Don't run the scripts in /etc/update-motd.d to refresh the motd file.
+
 EXAMPLES
 
 The suggested usage for /etc/pam.d/login is:
