* 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
--- /dev/null
+.\" 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)
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),
.\"}}}
.\"{{{ -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"
# 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
endif
ifeq ($(DISTRO),Debian)
+CPPFLAGS+= -DACCTON_OFF
BIN += mountpoint
SBIN += sulogin bootlogd
MAN1 += mountpoint.1
endif
ifeq ($(DISTRO),SuSE)
+CPPFLAGS+= -DUSE_SYSFS -DSANE_TIO -DSIGINT_ONLYONCE
BIN += mountpoint
SBIN += sulogin
USRBIN += utmpdump
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)
#%.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
runlevel: runlevel.o
-sulogin: LDLIBS += $(LCRYPT) $(SULOGIN_SELIBS) $(STATIC)
+sulogin: LDLIBS += $(SULOGINLIBS) $(STATIC)
sulogin: sulogin.o
wall: dowall.o wall.o
}
#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)
--- /dev/null
+/* 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;
+}
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;
}
-
#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"
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;
}
+#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.
*
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
* 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>
/* 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);
}
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();
}
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;