summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak2011-10-05 13:30:52 +0200
committerKarel Zak2011-10-26 23:17:17 +0200
commit4d8fc09c27d178eb187544270eeeebb0cd16ab36 (patch)
tree2f02ae0550179bbb65b207a5469939385ac94c6e
parentlogin: remove obsolete info from man page (diff)
downloadkernel-qcow2-util-linux-4d8fc09c27d178eb187544270eeeebb0cd16ab36.tar.gz
kernel-qcow2-util-linux-4d8fc09c27d178eb187544270eeeebb0cd16ab36.tar.xz
kernel-qcow2-util-linux-4d8fc09c27d178eb187544270eeeebb0cd16ab36.zip
login: rewrite motd(), use MOTD_FILE from login.defs
Note that Suse login(1) does not use any default for MOTD_FILE, so MOTD_FILE item in login.defs is required otherwise nothing is printed. We use (for backward compatibility) /etc/motd as default. Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--login-utils/Makefile.am3
-rw-r--r--login-utils/login.120
-rw-r--r--login-utils/login.c53
3 files changed, 53 insertions, 23 deletions
diff --git a/login-utils/Makefile.am b/login-utils/Makefile.am
index 84036fc2a..ada45553d 100644
--- a/login-utils/Makefile.am
+++ b/login-utils/Makefile.am
@@ -25,7 +25,8 @@ chfn_SOURCES = chfn.c $(chfn_chsh_common)
chsh_SOURCES = chsh.c $(chfn_chsh_common)
chfn_chsh_common = islocal.c setpwnam.c islocal.h setpwnam.h \
$(top_srcdir)/lib/env.c
-login_SOURCES = login.c $(top_srcdir)/lib/setproctitle.c
+login_SOURCES = login.c logindefs.c logindefs.h \
+ $(top_srcdir)/lib/setproctitle.c
vipw_SOURCES = vipw.c setpwnam.h
chfn_LDADD = $(login_ldadd_common)
diff --git a/login-utils/login.1 b/login-utils/login.1
index 50575cc22..8aba16f59 100644
--- a/login-utils/login.1
+++ b/login-utils/login.1
@@ -114,6 +114,26 @@ and
.I /etc/pam.d/remote
).
+
+.SH CONFIG FILE ITEMS
+.B login
+reads the
+.IR /etc/login.defs (5)
+configuration file. Note that the configuration file could be distributed with
+another package (e.g. shadow-utils). The following configuration items are
+relevant for
+.BR login (1):
+.PP
+\fBMOTD_FILE\fR (string)
+.RS 4
+If defined, ":" delimited list of "message of the day" files to be displayed
+upon login. The default value is "/etc/motd". If the \fBMOTD_FILE\fR item is
+empty or "quiet" login is enabled then the message of the day is not displayed.
+Note that the same functionality is also provided by
+.BR pam_motd (8)
+PAM module.
+.RE
+
.SH FILES
.nf
.I /var/run/utmp
diff --git a/login-utils/login.c b/login-utils/login.c
index f4172bfbb..6e7e4e27c 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -43,7 +43,6 @@
#include <grp.h>
#include <pwd.h>
#include <utmp.h>
-#include <setjmp.h>
#include <stdlib.h>
#include <sys/syslog.h>
#include <sys/sysmacros.h>
@@ -52,6 +51,7 @@
#include <lastlog.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
+#include <sys/sendfile.h>
#ifdef HAVE_LIBAUDIT
# include <libaudit.h>
@@ -68,6 +68,8 @@
#include "xalloc.h"
#include "writeall.h"
+#include "logindefs.h"
+
#define is_pam_failure(_rc) ((_rc) != PAM_SUCCESS)
#define LOGIN_MAX_TRIES 3
@@ -122,8 +124,6 @@ static int timeout = LOGIN_TIMEOUT;
static int child_pid = 0;
static volatile int got_sig = 0;
-jmp_buf motdinterrupt;
-
/*
* Robert Ambrose writes:
* A couple of my users have a problem with login processes hanging around
@@ -173,12 +173,6 @@ static void sig_handler(int signal)
kill(-child_pid, SIGHUP); /* because the shell often ignores SIGTERM */
}
-static void sigint(int sig __attribute__ ((__unused__)))
-{
- longjmp(motdinterrupt, 1);
-}
-
-
/* Should not be called from PAM code... */
static void sleepexit(int eval)
{
@@ -186,23 +180,38 @@ static void sleepexit(int eval)
exit(eval);
}
+/*
+ * Output the /etc/motd file
+ *
+ * motd() determines the name of a login announcement file and outputs it to
+ * the user's terminal at login time. The MOTD_FILE configuration option is a
+ * colon-delimited list of filenames. The empty MOTD_FILE option disables motd
+ * printing at all.
+ */
static void motd(void)
{
- int fd, nchars;
- void (*oldint) (int);
- char tbuf[8192];
+ char *motdlist, *motdfile, *cp;
+ const char *mb;
- if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
+ mb = getlogindefs_str("MOTD_FILE", _PATH_MOTDFILE);
+ if (!mb || !*mb)
return;
- oldint = signal(SIGINT, sigint);
- if (setjmp(motdinterrupt) == 0)
- while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) {
- if (write(fileno(stdout), tbuf, nchars)) {
- ; /* glibc warn_unused_result */
- }
- }
- signal(SIGINT, oldint);
- close(fd);
+
+ motdlist = xstrdup(mb);
+
+ for (cp = motdlist; (motdfile = strtok(cp, ":")); cp = NULL) {
+ struct stat st;
+ int fd;
+
+ if (stat(motdfile, &st) || !st.st_size)
+ continue;
+ fd = open(motdfile, O_RDONLY, 0);
+ if (fd < 0)
+ continue;
+
+ sendfile(fileno(stdout), fd, NULL, st.st_size);
+ close(fd);
+ }
}
/*