* Add fix for Debian bug #536574 -- Can be enabled by -DACCTON_OFF
authorDr. Werner Fink <werner@suse.de>
Tue, 23 Mar 2010 14:37:01 +0000 (14:37 +0000)
committerDr. Werner Fink <werner@suse.de>
Tue, 23 Mar 2010 14:37:01 +0000 (14:37 +0000)
 * Add helper program fstab-decode to make it easier to handle
   /etc/mtab content. Patch by Miloslav Trmac and Fedora.
 * Add fix for Debian bug #335023 - Make sure TERM is set on FreeBSD.
 * Add fix for Debian bug #374038 - Make it clear that shutdown -c can
   only cancel a waiting shutdown, not an active one.
 * Add not to pidof manual page about the use of readlink(2). Patch by
   Bill Nottingham and Fedora.
 * Add changes for Debian bug #68621 - Add PAM support for programs spawned
   by init on the console like sulogin. Based on patch by Topi Miettinen.

git-svn-id: svn://svn.sv.gnu.org/sysvinit/sysvinit/trunk@49 456724a4-4300-0410-8514-c89748c515a2

doc/Changelog
man/fstab-decode.8 [new file with mode: 0644]
man/pidof.8
man/shutdown.8
src/Makefile
src/bootlogd.c
src/fstab-decode.c [new file with mode: 0644]
src/ifdown.c
src/init.c
src/shutdown.c
src/utmpdump.c

index 45e2d422840ff26516ff16ea7f9defdd959c6033..1c707b4ba57b59027c0572ddae315dabe21d9bab 100644 (file)
@@ -57,6 +57,16 @@ sysvinit (2.88dsf) UNRELEASED; urgency=low
   * sulogin - add the possibility to reset the terminal io
   * Fix some minor problems
   * init - enable is_selinux_enabled() to detect selinuxfs
+  * Add fix for Debian bug #536574 -- Can be enabled by -DACCTON_OFF
+  * Add helper program fstab-decode to make it easier to handle
+    /etc/mtab content. Patch by Miloslav Trmac and Fedora.
+  * Add fix for Debian bug #335023 - Make sure TERM is set on FreeBSD.
+  * Add fix for Debian bug #374038 - Make it clear that shutdown -c can
+    only cancel a waiting shutdown, not an active one.
+  * Add not to pidof manual page about the use of readlink(2). Patch by
+    Bill Nottingham and Fedora.
+  * Add changes for Debian bug #68621 - Add PAM support for programs spawned
+    by init on the console like sulogin. Based on patch by Topi Miettinen.
 
  -- Petter Reinholdtsen <pere@hungry.com>  Sun, 12 Jul 2009 19:58:10 +0200
 
diff --git a/man/fstab-decode.8 b/man/fstab-decode.8
new file mode 100644 (file)
index 0000000..6e80021
--- /dev/null
@@ -0,0 +1,45 @@
+.\" A man page for fstab-decode(8).
+.\"
+.\" Copyright (C) 2006 Red Hat, Inc. All rights reserved.
+.\"
+.\" This copyrighted material is made available to anyone wishing to use,
+.\" modify, copy, or redistribute it subject to the terms and conditions of the
+.\" GNU General Public License v.2.
+.\"
+.\" This program is distributed in the hope that it will be useful, but WITHOUT
+.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+.\" more details.
+.\"
+.\" You should have received a copy of the GNU General Public License along
+.\" with this program; if not, write to the Free Software Foundation, Inc.,
+.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+.\"
+.\" Author: Miloslav Trmac <mitr@redhat.com>
+.TH fstab-decode 8 "May 2006"
+
+.SH NAME
+fstab-decode \- run a command with fstab-encoded arguments
+
+.SH SYNOPSIS
+\fB fstab-decode\fR \fICOMMAND\fR [\fIARGUMENT\fR]...
+
+.SH DESCRIPTION
+.B fstab-decode
+decodes escapes in the specified \FIARGUMENT\fRs
+and uses them to run \fICOMMAND\fR.
+The argument escaping uses the same rules as path escaping in
+\fB/etc/fstab\fR,
+.B /etc/mtab
+and \fB/proc/mtab\fR.
+
+.SH EXIT STATUS
+.B fstab-decode
+exits with status 127 if
+.I COMMAND
+can't be run.
+Otherwise it exits with the status returned by \fICOMMAND\fR.
+
+.SH EXAMPLES
+
+.B fstab-decode umount $(awk '$3 == "vfat" { print $2 }' /etc/fstab)
index 28db5c170c558540aacbef9c8029e52f3d8f1dbb..276a93cc395993cdbd379bbb83b1fc49b5aa29f3 100644 (file)
@@ -77,7 +77,11 @@ the program behaves according to the name under which it is called.
 When \fIpidof\fP is invoked with a full pathname to the program it
 should find the pid of, it is reasonably safe. Otherwise it is possible
 that it returns pids of running programs that happen to have the same name
-as the program you're after but are actually other programs.
+as the program you're after but are actually other programs. Note that
+that the executable name of running processes is calculated with
+.BR readlink (2),
+so symbolic links to executables will also match.
+
 .SH SEE ALSO
 .BR shutdown (8),
 .BR init (8),
index 8122e9ab46ca7f447eaa8eceb44f3868872298df..919a77e43eb6dfe2ffb9a9b9917329e1c4bdab47 100644 (file)
@@ -93,9 +93,10 @@ you'd expect.
 .\"}}}
 .\"{{{  -c
 .IP \fB\-c\fP
-Cancel an already running shutdown. With this option it is of course
-not possible to give the \fBtime\fP argument, but you can enter a
-explanatory message on the command line that will be sent to all users.
+Cancel a waiting shutdown. ("shutdown now" is no longer waiting.) With
+this option it is of course not possible to give the time argument, but
+you can enter explanatory message arguments on the command line that
+will be sent to all users.
 .\"}}}
 .\"{{{  -t sec
 .IP "\fB\-t\fP \fIsec\fP"
index a0861985440dbd0238e7aa41f9494cca764e7496..35c97128d4e7ae8b9a1a668adc2e25a900f66ff4 100644 (file)
@@ -8,19 +8,20 @@
 # Version:     @(#)Makefile  2.85-13  23-Mar-2004  miquels@cistron.nl
 #
 
+CPPFLAGS = -DUSE_PAM
 CFLAGS ?= -ansi -O2 -fomit-frame-pointer
-CFLAGS += -W -Wall -D_GNU_SOURCE
+override CFLAGS += -W -Wall -D_GNU_SOURCE
 STATIC =
 
 # For some known distributions we do not build all programs, otherwise we do.
 BIN    =
-SBIN   = init halt shutdown runlevel killall5
+SBIN   = init halt shutdown runlevel killall5 fstab-decode
 USRBIN = last mesg
 
 MAN1   = last.1 lastb.1 mesg.1
 MAN5   = initscript.5 inittab.5
 MAN8   = halt.8 init.8 killall5.8 pidof.8 poweroff.8 reboot.8 runlevel.8
-MAN8   += shutdown.8 telinit.8
+MAN8   += shutdown.8 telinit.8 fstab-decode.8
 
 ifeq ($(DISTRO),)
 BIN    += mountpoint
@@ -31,6 +32,7 @@ MAN8  += sulogin.8 bootlogd.8
 endif
 
 ifeq ($(DISTRO),Debian)
+CPPFLAGS+= -DACCTON_OFF
 BIN    += mountpoint
 SBIN   += sulogin bootlogd
 MAN1   += mountpoint.1
@@ -43,6 +45,7 @@ MAN1  += wall.1
 endif
 
 ifeq ($(DISTRO),SuSE)
+CPPFLAGS+= -DUSE_SYSFS -DSANE_TIO -DSIGINT_ONLYONCE
 BIN    += mountpoint
 SBIN   += sulogin
 USRBIN += utmpdump
@@ -50,28 +53,39 @@ MAN1        += utmpdump.1 mountpoint.1
 MAN8   += sulogin.8
 endif
 
+ID             = $(shell id -u)
 BIN_OWNER      = root
 BIN_GROUP      = root
 BIN_COMBO      = $(BIN_OWNER):$(BIN_GROUP)
 STRIP          = strip -s -R .comment
-INSTALL_EXEC   = install -o $(BIN_OWNER) -g $(BIN_GROUP) -m 755
-INSTALL_DATA   = install -o $(BIN_OWNER) -g $(BIN_GROUP) -m 644
+ifeq ($(ID),0)
+  INSTALL_EXEC = install -o $(BIN_OWNER) -g $(BIN_GROUP) -m 755
+  INSTALL_DATA = install -o $(BIN_OWNER) -g $(BIN_GROUP) -m 644
+else
+  INSTALL_EXEC = install -m 755
+  INSTALL_DATA = install -m 644
+endif
 INSTALL_DIR    = install -m 755 -d
 MANDIR         = /usr/share/man
 
 ifeq ($(WITH_SELINUX),yes)
-  SELINUX_DEF=-DWITH_SELINUX
-  INIT_SELIBS=-lsepol -lselinux
-  SULOGIN_SELIBS=-lselinux     
+  SELINUX_DEF  =  -DWITH_SELINUX
+  INITLIBS     += -lsepol -lselinux
+  SULOGINLIBS  = -lselinux     
 else
-  SELINUX_DEF=
-  INIT_SELIBS=
-  SULOGIN_SELIBS=
+  SELINUX_DEF  =
+  INITLIBS     =
+  SULOGINLIBS  =
+endif
+
+# Additional libs for GNU libc.
+ifneq ($(findstring -DUSE_PAM,$(CPPFLAGS)),)
+  INITLIBS     += -lpam -lpam_misc
 endif
 
 # Additional libs for GNU libc.
 ifneq ($(wildcard /usr/lib*/libcrypt.a),)
-LCRYPT         = -lcrypt
+  SULOGINLIBS  += -lcrypt
 endif
 
 all:           $(BIN) $(SBIN) $(USRBIN)
@@ -81,7 +95,7 @@ all:          $(BIN) $(SBIN) $(USRBIN)
 #%.o: %.c
 #      $(CC) $(CFLAGS) $(CPPFLAGS) -c $^ -o $@
 
-init:          LDLIBS += $(INIT_SELIBS) $(STATIC)
+init:          LDLIBS += $(INITLIBS) $(STATIC)
 init:          init.o init_utmp.o
 
 halt:          halt.o ifdown.o hddown.o utmp.o reboot.h
@@ -96,7 +110,7 @@ utmpdump:    utmpdump.o
 
 runlevel:      runlevel.o
 
-sulogin:       LDLIBS += $(LCRYPT) $(SULOGIN_SELIBS) $(STATIC)
+sulogin:       LDLIBS += $(SULOGINLIBS) $(STATIC)
 sulogin:       sulogin.o
 
 wall:          dowall.o wall.o
index 6ee982a902de03078bd943c18cc430ddfa4ec45e..570d3822bf117f5ee16711ccfcfa2e4beb7e1af0 100644 (file)
@@ -263,6 +263,9 @@ int consolename(char *res, int rlen)
        }
 
 #ifdef TIOCGDEV
+# ifndef  ENOIOCTLCMD
+#  define ENOIOCTLCMD  515
+# endif
        if (ioctl(0, TIOCGDEV, &kdev) == 0) {
                int r = findtty(res, "/dev", rlen, (dev_t)kdev);
                if (0 != r)
diff --git a/src/fstab-decode.c b/src/fstab-decode.c
new file mode 100644 (file)
index 0000000..4a162df
--- /dev/null
@@ -0,0 +1,86 @@
+/* fstab-decode(8).
+
+Copyright (c) 2006 Red Hat, Inc. All rights reserved.
+
+This copyrighted material is made available to anyone wishing to use, modify,
+copy, or redistribute it subject to the terms and conditions of the GNU General
+Public License v.2.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
+Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+Author: Miloslav Trmac <mitr@redhat.com> */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Decode the fstab-encoded string in place. */
+static void
+decode(char *s)
+{
+       const char *src;
+       char *dest;
+
+       src = s;
+       dest = s;
+       while (*src != '\0') {
+               if (*src != '\\')
+                       *dest = *src++;
+               else {
+                       static const struct repl {
+                               char orig[4];
+                               size_t len;
+                               char new;
+                       } repls[] = {
+#define R(X, Y) { X, sizeof(X) - 1, Y }
+                               R("\\", '\\'),
+                               R("011", '\t'),
+                               R("012", '\n'),
+                               R("040", ' '),
+                               R("134", '\\')
+#undef R
+                       };
+
+                       size_t i;
+
+                       for (i = 0; i < sizeof (repls) / sizeof (repls[0]);
+                            i++) {
+                               if (memcmp(src + 1, repls[i].orig,
+                                          repls[i].len) == 0) {
+                                       *dest = repls[i].new;
+                                       src += 1 + repls[i].len;
+                                       goto found;
+                               }
+                       }
+                       *dest = *src++;
+               found:
+                       ;
+               }
+               dest++;
+       }
+       *dest = '\0';
+}
+
+int
+main (int argc, char *argv[])
+{
+       size_t i;
+
+       if (argc < 2) {
+               fprintf(stderr, "Usage: fstab-decode command [arguments]\n");
+               return EXIT_FAILURE;
+       }
+       for (i = 2; i < (size_t)argc; i++)
+               decode(argv[i]);
+       execvp(argv[1], argv + 1);
+       fprintf(stderr, "fstab-decode: %s: %s\n", argv[1], strerror(errno));
+       return 127;
+}
index 42c0d6fd3f63334c2ef7709b4be51b2882ba3463..3048a359a0fc2779a2b78e3ed286d3a7c3c96797 100644 (file)
@@ -77,15 +77,33 @@ int ifdown(void)
                                continue;
                        if (strchr(ifr[i].ifr_name, ':') != NULL)
                                continue;
-                       ifr[i].ifr_flags &= ~(IFF_UP);
-                       if (ioctl(fd, SIOCSIFFLAGS, &ifr[i]) < 0) {
+
+                       /* Read interface flags */
+                       if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) < 0) {
                                fprintf(stderr, "ifdown: shutdown ");
                                perror(ifr[i].ifr_name);
+                               continue;
                        }
+                       /*
+                        * Expected in <net/if.h> according to
+                        * "UNIX Network Programming".
+                        */
+#ifdef ifr_flags
+# define IRFFLAGS      ifr_flags
+#else  /* Present on kFreeBSD */
+# define IRFFLAGS      ifr_flagshigh
+#endif
+                       if (ifr[i].IRFFLAGS & IFF_UP) {
+                               ifr[i].IRFFLAGS &= ~(IFF_UP);
+                               if (ioctl(fd, SIOCSIFFLAGS, &ifr[i]) < 0) {
+                                       fprintf(stderr, "ifdown: shutdown ");
+                                       perror(ifr[i].ifr_name);
+                               }
+                       }
+#undef IRFFLAGS
                }
        }
        close(fd);
 
        return 0;
 }
-
index feeeeaa0d8268f08747d40c0963a31a10680b926..271a64e0a2130135ff2747c42748a287687374d2 100644 (file)
 #include <sys/time.h>
 
 #ifdef WITH_SELINUX
-#include <selinux/selinux.h>
-#include <sys/mount.h>
+#  include <selinux/selinux.h>
+#  include <sys/mount.h>
 #endif
 
-
 #ifdef __i386__
 #  ifdef __GLIBC__
      /* GNU libc 2.x */
 #  endif
 #endif
 
+#ifdef USE_PAM
+#  include <security/pam_appl.h>
+#  include <security/pam_misc.h>
+#endif
+
 #include "init.h"
 #include "initreq.h"
 #include "paths.h"
@@ -746,6 +750,16 @@ void console_stty(void)
                return;
        }
 
+#ifdef __FreeBSD_kernel__
+       /*
+        * The kernel of FreeBSD expects userland to set TERM.  Usually, we want
+        * "cons25".  Later, gettys might disagree on this (i.e. we're not using
+        * syscons) but some boot scripts, like /etc/init.d/xserver-xorg, still
+        * need a non-dumb terminal.
+        */
+       putenv ("TERM=cons25");
+#endif
+
        (void) tcgetattr(fd, &tty);
 
        tty.c_cflag &= CBAUD|CBAUDEX|CSIZE|CSTOPB|PARENB|PARODD;
@@ -902,6 +916,20 @@ void init_freeenv(char **e)
 }
 
 
+#ifdef USE_PAM
+static pam_handle_t *pamh = NULL;
+static const struct pam_conv conv = { misc_conv, NULL };
+# define PAM_FAIL_CHECK(func, args...) \
+       { \
+               const int __ret = (func)(args); \
+               if (__ret != PAM_SUCCESS) { \
+                       initlog(L_VB, "%s", pam_strerror(pamh, __ret)); \
+                       pam_end(pamh, __ret); \
+                       exit(1); \
+               } \
+       }
+#endif /* USE_PAM */
+
 /*
  *     Fork and execute.
  *
@@ -1031,6 +1059,14 @@ int spawn(CHILD *ch, int *res)
 
                sigprocmask(SIG_SETMASK, &omask, NULL);
 
+#ifdef USE_PAM
+               PAM_FAIL_CHECK(pam_start, "init", "root" , &conv, &pamh);
+               PAM_FAIL_CHECK(pam_set_item, pamh, PAM_TTY, console_dev);
+               PAM_FAIL_CHECK(pam_acct_mgmt, pamh, PAM_SILENT);
+               PAM_FAIL_CHECK(pam_open_session, pamh, PAM_SILENT);
+               PAM_FAIL_CHECK(pam_setcred, pamh, PAM_ESTABLISH_CRED|PAM_SILENT);
+#endif
+
                /*
                 * Update utmp/wtmp file prior to starting
                 * any child.  This MUST be done right here in
index 397dcf5c03ec859b695721e83bfbdd1c6fdf60ba..7e997da84e3acee8f29b45e110969d625fc403df 100644 (file)
  *             along with this program; if not, write to the Free Software
  *             Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE   /* otherwise `extern char **environ' is missed */
+#endif
+#ifndef ACCTON_OFF
+# define ACCTON_OFF    0
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <time.h>
 #include <string.h>
+#include <errno.h>
 #include <unistd.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -330,7 +337,7 @@ void fastdown()
 
        /* First idle init. */
        if (kill(1, SIGTSTP) < 0) {
-               fprintf(stderr, "shutdown: can't idle init.\r\n");
+               fprintf(stderr, "shutdown: can't idle init: %s.\r\n", strerror(errno));
                exit(1);
        }
 
@@ -357,7 +364,17 @@ void fastdown()
        write_wtmp("shutdown", "~~", 0, RUN_LVL, "~~");
 
        /* This is for those who have quota installed. */
+#if defined(ACCTON_OFF)
+# if (ACCTON_OFF > 1) && (_BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500))
+       /* This is an alternative way to disable accounting, saving a fork() */
+       if (acct(NULL))
+               fprintf(stderr, "shutdown: can not stop process accounting: %s.\r\n", strerror(errno));
+# elif (ACCTON_OFF > 0)
+       spawn(1, "accton", "off", NULL);
+# else
        spawn(1, "accton", NULL);
+# endif
+#endif
        spawn(1, "quotaoff", "-a", NULL);
 
        sync();
index d9174c66bec4934b13a22f47be6332db5070929c..97f98697350b4b796589b8df678c9abcc9f52eab 100644 (file)
@@ -200,7 +200,11 @@ gettok(char *line, char *dest, int size, int eatspace)
 }
 
 void
+# ifdef __GNUC__
+undump(FILE *fp, int forever __attribute__((unused)), int oldfmt)
+#else
 undump(FILE *fp, int forever, int oldfmt)
+#endif
 {
        struct utmp ut;
        struct oldutmp uto;