diff options
author | Karel Zak | 2006-12-07 00:25:48 +0100 |
---|---|---|
committer | Karel Zak | 2006-12-07 00:25:48 +0100 |
commit | 364cda4857f7dd5e2b4e2eb7583a2eaa279ef4ed (patch) | |
tree | c60dfad813ca42bf619fe2ac8ce893d2331e508f /login-utils | |
parent | Imported from util-linux-2.11b tarball. (diff) | |
download | kernel-qcow2-util-linux-364cda4857f7dd5e2b4e2eb7583a2eaa279ef4ed.tar.gz kernel-qcow2-util-linux-364cda4857f7dd5e2b4e2eb7583a2eaa279ef4ed.tar.xz kernel-qcow2-util-linux-364cda4857f7dd5e2b4e2eb7583a2eaa279ef4ed.zip |
Imported from util-linux-2.11f tarball.
Diffstat (limited to 'login-utils')
-rw-r--r-- | login-utils/Makefile | 2 | ||||
-rw-r--r-- | login-utils/agetty.c | 6 | ||||
-rw-r--r-- | login-utils/checktty.c | 8 | ||||
-rw-r--r-- | login-utils/chsh.c | 40 | ||||
-rw-r--r-- | login-utils/initctl.8 | 26 | ||||
-rw-r--r-- | login-utils/login.c | 239 | ||||
-rw-r--r-- | login-utils/login.h | 2 | ||||
-rw-r--r-- | login-utils/shutdown.c | 28 | ||||
-rw-r--r-- | login-utils/simpleinit.8 | 19 | ||||
-rw-r--r-- | login-utils/simpleinit.c | 99 | ||||
-rw-r--r-- | login-utils/wall.c | 11 |
11 files changed, 271 insertions, 209 deletions
diff --git a/login-utils/Makefile b/login-utils/Makefile index e6b37b8a1..dc96f8780 100644 --- a/login-utils/Makefile +++ b/login-utils/Makefile @@ -83,7 +83,7 @@ all-getty: $(SBIN.GETTY) all-misc: $(USRBIN.MISC) # Rules for everything else - +login.o: ../MCONFIG checktty.o login.o: login.h cryptocard.o login.o: cryptocard.h chfn.o chsh.o islocal.o passwd.o: islocal.h diff --git a/login-utils/agetty.c b/login-utils/agetty.c index 3a30b16ba..c7f0f3d26 100644 --- a/login-utils/agetty.c +++ b/login-utils/agetty.c @@ -683,8 +683,12 @@ open_tty(tty, tp, local) * access for group tty) after the login has succeeded. */ + /* + * Let us use 0600 for Linux for the period between getty and login + */ + (void) chown(tty, 0, 0); /* root, sys */ - (void) chmod(tty, 0622); /* crw--w--w- */ + (void) chmod(tty, 0600); /* 0622: crw--w--w- */ errno = 0; /* ignore above errors */ } diff --git a/login-utils/checktty.c b/login-utils/checktty.c index e96647ea6..8171f44d2 100644 --- a/login-utils/checktty.c +++ b/login-utils/checktty.c @@ -33,7 +33,7 @@ #include "xstrncpy.h" #ifdef TESTING -struct hostent hostaddress; +char hostaddress[4]; char *hostname; void @@ -192,10 +192,10 @@ hnmatch(const char *hn, const char *pat) mask = (((unsigned long)y1<<24)+((unsigned long)y2<<16) +((unsigned long)y3<<8)+((unsigned long)y4)); - if (!hostaddress.h_addr_list || !hostaddress.h_addr_list[0]) - return 0; + if (hostaddress[0] == 0) + return 0; - ha = (unsigned char *)hostaddress.h_addr_list[0]; + ha = (unsigned char *)hostaddress; a = (((unsigned long)ha[0]<<24)+((unsigned long)ha[1]<<16) +((unsigned long)ha[2]<<8)+((unsigned long)ha[3])); return ((p & mask) == (a & mask)); diff --git a/login-utils/chsh.c b/login-utils/chsh.c index fd9b5899e..4be7e555f 100644 --- a/login-utils/chsh.c +++ b/login-utils/chsh.c @@ -201,11 +201,8 @@ main (int argc, char *argv[]) { * parse the command line arguments, and fill in "pinfo" with any * information from the command line. */ -static void parse_argv (argc, argv, pinfo) - int argc; - char *argv[]; - struct sinfo *pinfo; -{ +static void +parse_argv (int argc, char *argv[], struct sinfo *pinfo) { int index, c; static struct option long_options[] = { @@ -257,22 +254,20 @@ static void parse_argv (argc, argv, pinfo) * usage () -- * print out a usage message. */ -static void usage (fp) - FILE *fp; -{ - fprintf (fp, _("Usage: %s [ -s shell ] "), whoami); - fprintf (fp, _("[ --list-shells ] [ --help ] [ --version ]\n")); - fprintf (fp, _(" [ username ]\n")); +static void +usage (FILE *fp) { + fprintf (fp, + _("Usage: %s [ -s shell ] [ --list-shells ] " + "[ --help ] [ --version ]\n" + " [ username ]\n"), whoami); } /* * prompt () -- * ask the user for a given field and return it. */ -static char *prompt (question, def_val) - char *question; - char *def_val; -{ +static char * +prompt (char *question, char *def_val) { int len; char *ans, *cp; @@ -300,9 +295,8 @@ static char *prompt (question, def_val) * an error and return (-1). * if the shell is a bad idea, print a warning. */ -static int check_shell (shell) - char *shell; -{ +static int +check_shell (char *shell) { int i, c; if (*shell != '/') { @@ -354,9 +348,8 @@ static int check_shell (shell) * return true. if not, return false. * if the given shell is NULL, /etc/shells is outputted to stdout. */ -static boolean get_shell_list (shell_name) - char *shell_name; -{ +static boolean +get_shell_list (char *shell_name) { FILE *fp; boolean found; int len; @@ -391,9 +384,8 @@ static boolean get_shell_list (shell_name) /* * xmalloc () -- malloc that never fails. */ -static void *xmalloc (bytes) - int bytes; -{ +static void * +xmalloc (int bytes) { void *vp; vp = malloc (bytes); diff --git a/login-utils/initctl.8 b/login-utils/initctl.8 index 1aa421a02..2fade3f5f 100644 --- a/login-utils/initctl.8 +++ b/login-utils/initctl.8 @@ -1,4 +1,4 @@ -.\" Copyright (C) 2000 Richard Gooch +.\" Copyright (C) 2000-2001 Richard Gooch .\" .\" This program is free software; you can redistribute it and/or modify .\" it under the terms of the GNU General Public License as published by @@ -18,9 +18,9 @@ .\" The postal address is: .\" Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia. .\" -.\" initctl.8 Richard Gooch 6-NOV-2000 +.\" initctl.8 Richard Gooch 21-FEB-2001 .\" -.TH INITCTL 8 "6 Nov 2000" "Util-Linux Package" +.TH INITCTL 8 "21 Feb 2001" "Util-Linux Package" .SH NAME initctl \- utility to control simpleinit(8) .SH SYNOPSIS @@ -30,12 +30,12 @@ initctl \- utility to control simpleinit(8) \fBprovide service\fP .fi .SH OVERVIEW -The \fBneed\fP programme is designed to help improve the robustness, -scalability and readability of system boot scripts. It is now possible -to write a modularised set of boot scripts without the complex and -fragile numbered symlink scheme used in SysV-style boot scripts. Each -script can simply declare, using \fBneed\fP(8), what must run before -them. +The \fBinitctl\fP programme is designed to help improve the +robustness, scalability and readability of system boot scripts. It is +now possible to write a modularised set of boot scripts without the +complex and fragile numbered symlink scheme used in SysV-style boot +scripts. Each script can simply declare, using \fBneed\fP(8), what +must run before them. .SH DESCRIPTION for need The \fBneed\fP programme is a utility that tells \fBsimpleinit\fP(8) to start a \fIservice\fP (usually a script in \fI/sbin/init.d\fP) and @@ -83,15 +83,15 @@ The exit code from \fBprovide\fP is 0 if the service may be provided, init. It may block waiting for another provider which is initialising the service. .SH SIGNALS -\fBneed\fP(8) uses \fBSIGUSR1\fP, \fBSIGUSR2\fP and \fBSIGPOLL\fP for -communication with \fBsimpleinit\fP(8). Don't send these signals to -it. +\fBinitctl\fP(8) uses \fBSIGUSR1\fP, \fBSIGUSR2\fP and \fBSIGPOLL\fP +for communication with \fBsimpleinit\fP(8). Don't send these signals +to it. .SH FILES .PD 0 .TP 20 .BI /dev/initctl This is the control FIFO, created by \fBsimpleinit\fP(8), which -\fBneed\fP(8) writes commands to. +\fBinitctl\fP(8) writes commands to. .SH SEE ALSO .BR simpleinit (8), .BR init (8) diff --git a/login-utils/login.c b/login-utils/login.c index 1cf188fba..409507396 100644 --- a/login-utils/login.c +++ b/login-utils/login.c @@ -13,11 +13,7 @@ - The program uses BSD command line options to be used in connection with e.g. 'rlogind' i.e. 'new login'. - - HP features left out: logging of bad login attempts in /etc/btmp, - they are sent to syslog - - password expiry - + - HP features left out: password expiry '*' as login shell, add it if you need it - BSD features left out: quota checks @@ -168,23 +164,6 @@ #include "setproctitle.h" #endif -/* - * RedHat writes: - * we've got a REAL HACK to avoid telling people that they have - * mail because the imap server has left a turd in their inbox. - * It works, but it sucks... - * It turns out that the turd is always 523 bytes long, so we - * just check for that size. - */ -/* - * If you want to turn this strange hack off, set - #define REDHAT_IGNORED_MAILSIZE 0 - * In case people complain, this may become a configuration option, - * or perhaps this hack is thrown out again. - * A better solution would be to check the contents of this file.. - */ -#define REDHAT_IGNORED_MAILSIZE 523 - #if 0 /* from before we had a lastlog.h file in linux */ struct lastlog @@ -243,24 +222,26 @@ int timeout = 60; /* used in cryptocard.c */ #endif struct passwd *pwd; /* used in cryptocard.c */ -struct hostent hostaddress; /* used in checktty.c */ -char term[64], *hostname, *username, *tty; +char hostaddress[4]; /* used in checktty.c */ +char *hostname; /* idem */ +static char *username, *tty_name, *tty_number; static char thishost[100]; static int failures = 1; #ifndef __linux__ struct sgttyb sgttyb; struct tchars tc = { - CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK - }; + CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK +}; struct ltchars ltc = { - CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT - }; + CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT +}; #endif -const char *months[] = -{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec" }; +const char *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; /* Nice and simple code provided by Linus Torvalds 16-Feb-93 */ /* Nonblocking stuff by Maciej W. Rozycki, macro@ds2.pg.gda.pl, 1999. @@ -271,8 +252,7 @@ const char *months[] = leaving the decision to make a connection to getty (where it actually belongs). */ static void -opentty(const char * tty) -{ +opentty(const char * tty) { int i; int fd = open(tty, O_RDWR | O_NONBLOCK); int flags = fcntl(fd, F_GETFL); @@ -290,8 +270,7 @@ opentty(const char * tty) /* true if the filedescriptor fd is a console tty, very Linux specific */ static int -consoletty(int fd) -{ +consoletty(int fd) { #ifdef __linux__ struct stat stb; @@ -304,6 +283,47 @@ consoletty(int fd) return 0; } +#if USE_PAM +/* + * Log failed login attempts in _PATH_BTMP if that exists. + * Must be called only with username the name of an actual user. + * The most common login failure is to give password instead of username. + */ +#define _PATH_BTMP "/var/log/btmp" +static void +logbtmp(const char *line, const char *username, const char *hostname) { + struct utmp ut; + + memset(&ut, 0, sizeof(ut)); + + strncpy(ut.ut_user, username ? username : "(unknown)", + sizeof(ut.ut_user)); + + strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); + xstrncpy(ut.ut_line, line, sizeof(ut.ut_line)); + +#if defined(_HAVE_UT_TV) /* in <utmpbits.h> included by <utmp.h> */ + gettimeofday(&ut.ut_tv, NULL); +#else + { + time_t t; + time(&t); + ut.ut_time = t; /* ut_time is not always a time_t */ + } +#endif + + ut.ut_type = LOGIN_PROCESS; /* XXX doesn't matter */ + ut.ut_pid = getpid(); + if (hostname) { + xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); + if (hostaddress[0]) + memcpy(&ut.ut_addr, hostaddress, sizeof(ut.ut_addr)); + } +#ifdef HAVE_updwtmp /* bad luck for ancient systems */ + updwtmp(_PATH_BTMP, &ut); +#endif +} +#endif /* USE_PAM */ int main(int argc, char **argv) @@ -363,7 +383,7 @@ main(int argc, char **argv) xstrncpy(thishost, tbuf, sizeof(thishost)); domain = index(tbuf, '.'); - username = tty = hostname = NULL; + username = tty_name = hostname = NULL; fflag = hflag = pflag = 0; passwd_req = 1; @@ -383,14 +403,16 @@ main(int argc, char **argv) if (domain && (p = index(optarg, '.')) && strcasecmp(p, domain) == 0) *p = 0; + hostname = strdup(optarg); /* strdup: Ambrose C. Li */ - { - struct hostent *he = gethostbyname(hostname); - if (he) { - memcpy(&hostaddress, he, sizeof(hostaddress)); - } else { - memset(&hostaddress, 0, sizeof(hostaddress)); - } + { + struct hostent *he = gethostbyname(hostname); + + /* he points to static storage; copy the part we use */ + hostaddress[0] = 0; + if (he && he->h_addr_list && he->h_addr_list[0]) + memcpy(hostaddress, he->h_addr_list[0], + sizeof(hostaddress)); } break; @@ -430,8 +452,7 @@ main(int argc, char **argv) ioctl(0, TIOCSETP, &sgttyb); /* - * Be sure that we're in - * blocking mode!!! + * Be sure that we're in blocking mode!!! * This is really for HPUX */ ioctlval = 0; @@ -448,16 +469,23 @@ main(int argc, char **argv) ttyn = tname; } -#ifdef CHOWNVCS - /* find names of Virtual Console devices, for later mode change */ - { + if (strncmp(ttyn, "/dev/", 5) == 0) + tty_name = ttyn+5; + else + tty_name = ttyn; + + if (strncmp(ttyn, "/dev/tty", 8) == 0) + tty_number = ttyn+8; + else { char *p = ttyn; - /* find number of tty */ while (*p && !isdigit(*p)) p++; - - strcpy(vcsn, "/dev/vcs"); strcat(vcsn, p); - strcpy(vcsan, "/dev/vcsa"); strcat(vcsan, p); + tty_number = p; } + +#ifdef CHOWNVCS + /* find names of Virtual Console devices, for later mode change */ + snprintf(vcsn, sizeof(vcsn), "/dev/vcs%s", tty_number); + snprintf(vcsan, sizeof(vcsan), "/dev/vcsa%s", tty_number); #endif setpgrp(); @@ -469,12 +497,15 @@ main(int argc, char **argv) ttt = tt; ttt.c_cflag &= ~HUPCL; - if((chown(ttyn, 0, 0) == 0) && (chmod(ttyn, TTY_MODE) == 0)) { - tcsetattr(0,TCSAFLUSH,&ttt); - signal(SIGHUP, SIG_IGN); /* so vhangup() wont kill us */ - vhangup(); - signal(SIGHUP, SIG_DFL); - } + /* These can fail, e.g. with ttyn on a read-only filesystem */ + chown(ttyn, 0, 0); + chmod(ttyn, TTY_MODE); + + /* Kill processes left on this tty */ + tcsetattr(0,TCSAFLUSH,&ttt); + signal(SIGHUP, SIG_IGN); /* so vhangup() wont kill us */ + vhangup(); + signal(SIGHUP, SIG_DFL); setsid(); @@ -484,11 +515,6 @@ main(int argc, char **argv) tcsetattr(0,TCSAFLUSH,&tt); } - if (strncmp(ttyn, "/dev/", 5) == 0) - tty = ttyn+5; - else - tty = ttyn; - openlog("login", LOG_ODELAY, LOG_AUTHPRIV); #if 0 @@ -515,7 +541,7 @@ main(int argc, char **argv) depending on how much we know */ retcode = pam_set_item(pamh, PAM_RHOST, hostname); PAM_FAIL_CHECK; - retcode = pam_set_item(pamh, PAM_TTY, tty); + retcode = pam_set_item(pamh, PAM_TTY, tty_name); PAM_FAIL_CHECK; /* @@ -545,6 +571,11 @@ main(int argc, char **argv) if(passwd_req == 1) { int failcount=0; + /* if we didn't get a user on the command line, set it to NULL */ + pam_get_item(pamh, PAM_USER, (const void **) &username); + if (!username) + pam_set_item(pamh, PAM_USER, NULL); + /* there may be better ways to deal with some of these conditions, but at least this way I don't think we'll be giving away information... */ @@ -558,8 +589,11 @@ main(int argc, char **argv) (retcode == PAM_CRED_INSUFFICIENT) || (retcode == PAM_AUTHINFO_UNAVAIL))) { pam_get_item(pamh, PAM_USER, (const void **) &username); + syslog(LOG_NOTICE,_("FAILED LOGIN %d FROM %s FOR %s, %s"), - failcount, hostname, username, pam_strerror(pamh, retcode)); + failcount, hostname, username, pam_strerror(pamh, retcode)); + logbtmp(tty_name, username, hostname); + fprintf(stderr,_("Login incorrect\n\n")); pam_set_item(pamh,PAM_USER,NULL); retcode = pam_authenticate(pamh, 0); @@ -568,13 +602,14 @@ main(int argc, char **argv) if (retcode != PAM_SUCCESS) { pam_get_item(pamh, PAM_USER, (const void **) &username); - if (retcode == PAM_MAXTRIES) + if (retcode == PAM_MAXTRIES) syslog(LOG_NOTICE,_("TOO MANY LOGIN TRIES (%d) FROM %s FOR " "%s, %s"), failcount, hostname, username, pam_strerror(pamh, retcode)); else syslog(LOG_NOTICE,_("FAILED LOGIN SESSION FROM %s FOR %s, %s"), hostname, username, pam_strerror(pamh, retcode)); + logbtmp(tty_name, username, hostname); fprintf(stderr,_("\nLogin incorrect\n")); pam_end(pamh, retcode); @@ -651,7 +686,7 @@ main(int argc, char **argv) if (pwd) { initgroups(username, pwd->pw_gid); - checktty(username, tty, pwd); /* in checktty.c */ + checktty(username, tty_name, pwd); /* in checktty.c */ } /* if user not super-user, check for disabled logins */ @@ -673,7 +708,7 @@ main(int argc, char **argv) * If trying to log in as root, but with insecure terminal, * refuse the login attempt. */ - if (pwd && pwd->pw_uid == 0 && !rootterm(tty)) { + if (pwd && pwd->pw_uid == 0 && !rootterm(tty_name)) { fprintf(stderr, _("%s login refused on this terminal.\n"), pwd->pw_name); @@ -681,11 +716,11 @@ main(int argc, char **argv) if (hostname) syslog(LOG_NOTICE, _("LOGIN %s REFUSED FROM %s ON TTY %s"), - pwd->pw_name, hostname, tty); + pwd->pw_name, hostname, tty_name); else syslog(LOG_NOTICE, _("LOGIN %s REFUSED ON TTY %s"), - pwd->pw_name, tty); + pwd->pw_name, tty_name); continue; } @@ -833,8 +868,8 @@ Michael Riepe <michael@stud.uni-hannover.de> if (utp == NULL) { setutent(); ut.ut_type = LOGIN_PROCESS; - strncpy(ut.ut_id, ttyn + 8, sizeof(ut.ut_id)); - strncpy(ut.ut_line, ttyn + 5, sizeof(ut.ut_line)); + strncpy(ut.ut_id, tty_number, sizeof(ut.ut_id)); + strncpy(ut.ut_line, tty_name, sizeof(ut.ut_line)); utp = getutid(&ut); } @@ -846,27 +881,26 @@ Michael Riepe <michael@stud.uni-hannover.de> } if (ut.ut_id[0] == 0) - strncpy(ut.ut_id, ttyn + 8, sizeof(ut.ut_id)); + strncpy(ut.ut_id, tty_number, sizeof(ut.ut_id)); strncpy(ut.ut_user, username, sizeof(ut.ut_user)); - xstrncpy(ut.ut_line, ttyn + 5, sizeof(ut.ut_line)); + xstrncpy(ut.ut_line, tty_name, sizeof(ut.ut_line)); #ifdef _HAVE_UT_TV /* in <utmpbits.h> included by <utmp.h> */ gettimeofday(&ut.ut_tv, NULL); #else { - time_t t; - time(&t); - ut.ut_time = t; /* ut_time is not always a time_t */ + time_t t; + time(&t); + ut.ut_time = t; /* ut_time is not always a time_t */ /* glibc2 #defines it as ut_tv.tv_sec */ } #endif ut.ut_type = USER_PROCESS; ut.ut_pid = mypid; if (hostname) { - xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); - if (hostaddress.h_addr_list) - memcpy(&ut.ut_addr, hostaddress.h_addr_list[0], - sizeof(ut.ut_addr)); + xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); + if (hostaddress[0]) + memcpy(&ut.ut_addr, hostaddress, sizeof(ut.ut_addr)); } pututline(&ut); @@ -980,14 +1014,12 @@ Michael Riepe <michael@stud.uni-hannover.de> #ifdef USE_PAM { int i; - const char * const * env; - - env = (const char * const *)pam_getenvlist(pamh); + char ** env = pam_getenvlist(pamh); if (env != NULL) { - for (i=0; env[i++]; ) { - putenv(env[i-1]); - /* D(("env[%d] = %s", i-1,env[i-1])); */ + for (i=0; env[i]; i++) { + putenv(env[i]); + /* D(("env[%d] = %s", i,env[i])); */ } } } @@ -997,8 +1029,8 @@ Michael Riepe <michael@stud.uni-hannover.de> setproctitle("login", username); #endif - if (tty[sizeof("tty")-1] == 'S') - syslog(LOG_INFO, _("DIALUP AT %s BY %s"), tty, pwd->pw_name); + if (!strncmp(tty_name, "ttyS", 4)) + syslog(LOG_INFO, _("DIALUP AT %s BY %s"), tty_name, pwd->pw_name); /* allow tracking of good logins. -steve philp (sphilp@mail.alliance.net) */ @@ -1006,15 +1038,15 @@ Michael Riepe <michael@stud.uni-hannover.de> if (pwd->pw_uid == 0) { if (hostname) syslog(LOG_NOTICE, _("ROOT LOGIN ON %s FROM %s"), - tty, hostname); + tty_name, hostname); else - syslog(LOG_NOTICE, _("ROOT LOGIN ON %s"), tty); + syslog(LOG_NOTICE, _("ROOT LOGIN ON %s"), tty_name); } else { if (hostname) - syslog(LOG_INFO, _("LOGIN ON %s BY %s FROM %s"), tty, + syslog(LOG_INFO, _("LOGIN ON %s BY %s FROM %s"), tty_name, pwd->pw_name, hostname); else - syslog(LOG_INFO, _("LOGIN ON %s BY %s"), tty, + syslog(LOG_INFO, _("LOGIN ON %s BY %s"), tty_name, pwd->pw_name); } @@ -1024,8 +1056,7 @@ Michael Riepe <michael@stud.uni-hannover.de> motd(); mail = getenv("MAIL"); - if (mail && stat(mail, &st) == 0 && st.st_size != 0 - && st.st_size != REDHAT_IGNORED_MAILSIZE) { + if (mail && stat(mail, &st) == 0 && st.st_size != 0) { printf(_("You have %smail.\n"), (st.st_mtime > st.st_atime) ? _("new ") : ""); } @@ -1034,7 +1065,6 @@ Michael Riepe <michael@stud.uni-hannover.de> signal(SIGALRM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGTSTP, SIG_IGN); - signal(SIGHUP, SIG_DFL); #ifdef USE_PAM /* @@ -1048,6 +1078,8 @@ Michael Riepe <michael@stud.uni-hannover.de> * Solution: use TIOCNOTTY and setsid(). */ signal(SIGINT, SIG_IGN); + signal(SIGHUP, SIG_IGN); /* ignore signal from TIOCNOTTY below */ + childPid = fork(); if (childPid < 0) { int errsv = errno; @@ -1057,7 +1089,6 @@ Michael Riepe <michael@stud.uni-hannover.de> exit(0); } else if (childPid) { /* parent - wait for child to finish, then cleanup session */ - signal(SIGHUP, SIG_IGN); /* ignore signal from TIOCNOTTY */ ioctl(0, TIOCNOTTY, NULL); signal(SIGHUP, SIG_DFL); @@ -1067,7 +1098,10 @@ Michael Riepe <michael@stud.uni-hannover.de> } /* child */ setsid(); + /* reopen, as we need controlling tty in the child */ + opentty(ttyn); #endif + signal(SIGHUP, SIG_DFL); signal(SIGINT, SIG_DFL); /* discard permissions last so can't get killed and drop core */ @@ -1192,7 +1226,7 @@ rootterm(char * ttyn) { struct ttyent *t; - return((t = getttynam(ttyn)) && t->ty_status&TTY_SECURE); + return((t = getttynam(ttyn)) && (t->ty_status&TTY_SECURE)); } #else { @@ -1286,7 +1320,7 @@ dolastlog(int quiet) { } memset((char *)&ll, 0, sizeof(ll)); time(&ll.ll_time); - xstrncpy(ll.ll_line, tty, sizeof(ll.ll_line)); + xstrncpy(ll.ll_line, tty_name, sizeof(ll.ll_line)); if (hostname) xstrncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); @@ -1296,22 +1330,21 @@ dolastlog(int quiet) { } void -badlogin(const char *name) -{ +badlogin(const char *name) { if (failures == 1) { if (hostname) syslog(LOG_NOTICE, _("LOGIN FAILURE FROM %s, %s"), hostname, name); else syslog(LOG_NOTICE, _("LOGIN FAILURE ON %s, %s"), - tty, name); + tty_name, name); } else { if (hostname) syslog(LOG_NOTICE, _("%d LOGIN FAILURES FROM %s, %s"), failures, hostname, name); else syslog(LOG_NOTICE, _("%d LOGIN FAILURES ON %s, %s"), - failures, tty, name); + failures, tty_name, name); } } diff --git a/login-utils/login.h b/login-utils/login.h index 14b698e32..c64502dcc 100644 --- a/login-utils/login.h +++ b/login-utils/login.h @@ -1,7 +1,7 @@ /* defined in login.c */ extern void badlogin(const char *s); extern void sleepexit(int); -extern struct hostent hostaddress; +extern char hostaddress[4]; extern char *hostname; /* defined in checktty.c */ diff --git a/login-utils/shutdown.c b/login-utils/shutdown.c index 036064aad..c7efe746e 100644 --- a/login-utils/shutdown.c +++ b/login-utils/shutdown.c @@ -46,6 +46,9 @@ * - do not unmount devfs (otherwise get harmless but annoying messages) * - created syncwait() for faster shutting down * - kill getty processes + * 2001-05-12 Richard Gooch <rgooch@atnf.csiro.au> + * - unblock all signals (sigmask from simpleinit(8) stopped sleep(3)) + * - close all files */ #include <stdio.h> @@ -137,14 +140,18 @@ iswhitespace(int a) { int main(int argc, char *argv[]) { - int c,i; - int fd; + int c, i, fd; char *ptr; - if (getpid () == 1) { - for (i = 0; i < getdtablesize (); i++) close (i); - while (1) wait (NULL); /* Grim reaper never stops */ + i = getdtablesize (); + for (fd = 3; fd < i; fd++) close (fd); + if (getpid () == 1) + { + for (fd = 0; fd < 3; fd++) close (fd); + while (1) wait (NULL); /* Grim reaper never stops */ } + sigsetmask (0); /* simpleinit(8) blocks all signals: undo for ALRM */ + for (i = 1; i < NSIG; i++) signal (i, SIG_DFL); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -373,6 +380,7 @@ main(int argc, char *argv[]) #ifndef DEBUGGING /* a gentle kill of all other processes except init */ kill_mortals (SIGTERM); + for (fd = 0; fd < 3; fd++) close (fd); stop_finalprog (); sleep (1); /* Time for saves to start */ kill (1, SIGTERM); /* Tell init to kill spawned gettys */ @@ -381,11 +389,10 @@ main(int argc, char *argv[]) system ("/sbin/initctl -r"); /* Roll back services */ syncwait (1); my_puts ("Sending SIGTERM to all remaining processes..."); - kill(-1, SIGTERM); - sleep(2); /* default 2, some people need 5 */ + kill (-1, SIGTERM); + sleep (2); /* Default 2, some people need 5 */ - /* now use brute force... */ - kill(-1, SIGKILL); + kill (-1, SIGKILL); /* Now use brute force... */ /* turn off accounting */ acct(NULL); @@ -472,7 +479,8 @@ write_user(struct utmp *ut) if((fd = open(term, O_WRONLY|O_NONBLOCK)) < 0) return; - sprintf(msg, _("\007URGENT: broadcast message from %s:"), whom); + msg[0] = '\007'; /* gettext crashes on \a */ + sprintf(msg+1, _("URGENT: broadcast message from %s:"), whom); WRCRLF; WR(msg); WRCRLF; diff --git a/login-utils/simpleinit.8 b/login-utils/simpleinit.8 index f367f2f63..2c3e08b2b 100644 --- a/login-utils/simpleinit.8 +++ b/login-utils/simpleinit.8 @@ -1,7 +1,7 @@ .\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu) .\" May be distributed under the GNU General Public License .\" " for emacs's hilit19 mode :-) -.TH SIMPLEINIT 8 "4 November 2000" "Linux 0.99" "Linux Programmer's Manual" +.TH SIMPLEINIT 8 "25 February 2001" "Linux 0.99" "Linux Programmer's Manual" .SH NAME simpleinit \- process control initialization .SH SYNOPSIS @@ -97,12 +97,15 @@ parallel. See the \fBneed\fP(8) programme for details on how to elegantly control order of execution and manage dependencies. The \fBPATH\fP value is assigned to the PATH environment variable of -child processes (boot scripts). The \fBINIT_PATH\fP value is used by -simpleinit(8) itself to find the location of scripts to run (if an -absolute path is not given). If unset the default value \fBPATH\fP is -used. This separation allows boot scripts to invoke programmes of the -same name without conflict and without needing to specify absolute -paths. +child processes (boot scripts). + +The \fBINIT_PATH\fP value is used by simpleinit(8) itself to find the +location of scripts to run (if an absolute path is not given). If +unset and the boot programme is a directory, that directory is used. +Finally, if the script cannot be found in this path, the standard +\fBPATH\fP is used. This separation allows boot scripts to invoke +programmes of the same name without conflict and without needing to +specify absolute paths. The \fBfinalprog\fP value specifies the path of the programme to run after all \fBgetty\fP(8) instances are spawned. At bootup, it is @@ -151,7 +154,7 @@ remount (read-only) the root filesystem, even if the old inode for the .BR getty (8), .BR agetty (8), .BR shutdown (8), -.BR need (8) +.BR initctl (8) .SH BUGS This program is called .B simpleinit diff --git a/login-utils/simpleinit.c b/login-utils/simpleinit.c index 56f10455a..9c08a03a6 100644 --- a/login-utils/simpleinit.c +++ b/login-utils/simpleinit.c @@ -1,5 +1,5 @@ /* simpleinit.c - poe@daimi.aau.dk */ -/* Version 2.0.1 */ +/* Version 2.0.2 */ /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> * - added Native Language Support @@ -9,6 +9,10 @@ * - fixed race when reading from pipe and reaping children * 2001-02-18 sam@quux.dropbear.id.au * - fixed bug in <get_path>: multiple INIT_PATH components did not work + * 2001-02-21 Richard Gooch <rgooch@atnf.csiro.au> + * - block signals in handlers, so that longjmp() doesn't kill context + * 2001-02-25 Richard Gooch <rgooch@atnf.csiro.au> + * - make default INIT_PATH the boot_prog (if it is a directory) - YECCH */ #include <sys/types.h> @@ -76,6 +80,8 @@ static char script_prefix[PATH_SIZE] = "\0"; static char final_prog[PATH_SIZE] = "\0"; static char init_path[PATH_SIZE] = "\0"; static int caught_sigint = 0; +static int no_reboot = 0; +static pid_t rc_child = -1; static const char *initctl_name = "/dev/initctl"; static int initctl_fd = -1; static volatile int do_longjmp = 0; @@ -89,9 +95,9 @@ static int process_path (const char *path, int (*func) (const char *path), static int preload_file (const char *path); static int run_file (const char *path); static void spawn (int i), read_inittab (void); -static void hup_handler (int sig); +static void sighup_handler (int sig); static void sigtstp_handler (int sig); -static void int_handler (int sig); +static void sigint_handler (int sig); static void sigchild_handler (int sig); static void sigquit_handler (int sig); static void sigterm_handler (int sig); @@ -134,7 +140,7 @@ static void enter_single (void) int main(int argc, char *argv[]) { - int vec,i; + int vec, i; int want_single = 0; pid_t pid; struct sigaction sa; @@ -143,8 +149,10 @@ int main(int argc, char *argv[]) #ifdef SET_TZ set_tz(); #endif - signal (SIGINT, int_handler); - sigemptyset (&sa.sa_mask); + sigfillset (&sa.sa_mask); /* longjmp and nested signals don't mix */ + sa.sa_flags = SA_ONESHOT; + sa.sa_handler = sigint_handler; + sigaction (SIGINT, &sa, NULL); sa.sa_flags = 0; sa.sa_handler = sigtstp_handler; sigaction (SIGTSTP, &sa, NULL); @@ -166,6 +174,7 @@ int main(int argc, char *argv[]) read_inittab (); for (i = 1; i < argc; i++) { if (strcmp (argv[i], "single") == 0) want_single = 1; + else if (strcmp (argv[i], "-noreboot") == 0) no_reboot = 1; else { char path[PATH_SIZE]; @@ -175,6 +184,17 @@ int main(int argc, char *argv[]) strcpy (boot_prog, path); } } + if (init_path[0] == '\0') + { + struct stat statbuf; + + if ( (stat (boot_prog, &statbuf) == 0) && S_ISDIR (statbuf.st_mode) ) + { + strcpy (init_path, boot_prog); + i = strlen (init_path); + if (init_path[i - 1] == '/') init_path[i - 1] = '\0'; + } + } if ( ( initctl_fd = open (initctl_name, O_RDWR, 0) ) < 0 ) { mkfifo (initctl_name, S_IRUSR | S_IWUSR); @@ -185,12 +205,12 @@ int main(int argc, char *argv[]) if ( want_single || (access (_PATH_SINGLE, R_OK) == 0) ) do_single (); /*If we get a SIGTSTP before multi-user mode, do nothing*/ - while(stopped) + while (stopped) pause(); if ( do_rc_tty (boot_prog) ) do_single (); - while(stopped) /*Also if /etc/rc fails & we get SIGTSTP*/ + while (stopped) /* Also if /etc/rc fails & we get SIGTSTP */ pause(); write_wtmp(); /* write boottime record */ @@ -204,7 +224,7 @@ int main(int argc, char *argv[]) } exit(0); #endif - signal(SIGHUP, hup_handler); + signal (SIGHUP, sighup_handler); /* Better semantics with signal(2) */ for (i = 0; i < getdtablesize (); i++) if (i != initctl_fd) close (i); @@ -326,14 +346,14 @@ static void do_single (void) static int do_rc_tty (const char *path) { int status; - pid_t pid, child; + pid_t pid; sigset_t ss; if (caught_sigint) return 0; process_path (path, preload_file, 0); /* Launch off a subprocess to start a new session (required for frobbing the TTY) and capture control-C */ - switch ( child = fork () ) + switch ( rc_child = fork () ) { case 0: /* Child */ for (status = 1; status < NSIG; status++) signal (status, SIG_DFL); @@ -355,12 +375,12 @@ static int do_rc_tty (const char *path) process_path (path, run_file, 0); while (1) { - if ( ( pid = mywait (&status) ) == child ) + if ( ( pid = mywait (&status) ) == rc_child ) return (WTERMSIG (status) == SIGINT) ? 0 : 1; if (pid < 0) break; } - kill (child, SIGKILL); - while (waitpid (child, NULL, 0) != child) /* Nothing */; + kill (rc_child, SIGKILL); + while (waitpid (rc_child, NULL, 0) != rc_child) /* Nothing */; return 0; } /* End Function do_rc_tty */ @@ -601,17 +621,16 @@ static void read_inittab (void) if (access (path, R_OK | X_OK) == 0) strcpy (boot_prog, path); } -} +} /* End Function read_inittab */ -static void hup_handler (int sig) +static void sighup_handler (int sig) { int i,j; int oldnum; struct initline savetab[NUMCMD]; int had_already; - (void) signal(SIGHUP, SIG_IGN); - + signal (SIGHUP, SIG_IGN); memcpy(savetab, inittab, NUMCMD * sizeof(struct initline)); oldnum = numcmd; read_inittab (); @@ -625,16 +644,15 @@ static void hup_handler (int sig) spawn(i); } } - if(!had_already) spawn(i); + if (!had_already) spawn (i); } - - (void) signal(SIGHUP, hup_handler); -} + signal (SIGHUP, sighup_handler); +} /* End Function sighup_handler */ static void sigtstp_handler (int sig) { stopped = ~stopped; - if (!stopped) hup_handler (sig); + if (!stopped) sighup_handler (sig); } /* End Function sigtstp_handler */ static void sigterm_handler (int sig) @@ -645,22 +663,23 @@ static void sigterm_handler (int sig) if (inittab[i].pid > 0) kill (inittab[i].pid, SIGTERM); } /* End Function sigterm_handler */ -static void int_handler (int sig) +static void sigint_handler (int sig) { - pid_t pid; - - caught_sigint = 1; - sync(); - sync(); - pid = fork(); - if (pid > 0) - return; - if (pid == 0) /* reboot properly... */ - execl(_PATH_REBOOT, _PATH_REBOOT, (char *)0); + pid_t pid; - /* fork or exec failed, try the hard way... */ - my_reboot(LINUX_REBOOT_CMD_RESTART); -} + caught_sigint = 1; + kill (rc_child, SIGKILL); + if (no_reboot) _exit (1) /*kill (0, SIGKILL)*/; + sync (); + sync (); + pid = fork (); + if (pid > 0) return; /* Parent */ + if (pid == 0) /* Child: reboot properly... */ + execl (_PATH_REBOOT, _PATH_REBOOT, (char *) 0); + + /* fork or exec failed, try the hard way... */ + my_reboot (LINUX_REBOOT_CMD_RESTART); +} /* End Function sigint_handler */ static void sigchild_handler (int sig) { @@ -708,7 +727,7 @@ static void write_wtmp (void) flock(lf, LOCK_UN|LOCK_NB); close(lf); } -} +} /* End Function write_wtmp */ struct needer_struct @@ -885,7 +904,9 @@ static void process_command (const struct command_struct *command) dup2 (1, 2); execlp (get_path (victim->first_service->name), victim->first_service->name, "stop", NULL); - err ( _("error running programme\n") ); + sprintf (txt, _("error stopping service: \"%s\""), + victim->first_service->name); + err (txt); _exit (SIG_NOT_STOPPED); } else if (pid == -1) break; /* Error */ diff --git a/login-utils/wall.c b/login-utils/wall.c index 3a13fe7ba..744c910f0 100644 --- a/login-utils/wall.c +++ b/login-utils/wall.c @@ -199,7 +199,8 @@ makemsg(fname) exit(1); } if (!freopen(fname, "r", stdin)) { - fprintf(stderr, _("%s: can't read %s.\n"), progname, fname); + fprintf(stderr, _("%s: can't read %s.\n"), + progname, fname); exit(1); } } @@ -212,16 +213,16 @@ makemsg(fname) putc('\r', fp); putc('\n', fp); cnt = 0; - } else { - carefulputc(ch, fp); } + carefulputc(ch, fp); } } - (void)fprintf(fp, "%79s\r\n", " "); + fprintf(fp, "%79s\r\n", " "); rewind(fp); if (fstat(fd, &sbuf)) { - (void)fprintf(stderr, _("%s: can't stat temporary file.\n"), progname); + fprintf(stderr, _("%s: can't stat temporary file.\n"), + progname); exit(1); } mbufsize = sbuf.st_size; |