jfh@rpp386.Dallas.TX.US (John F. Haugh II) (03/09/89)
This is patch number 5. It fixes some bugs in passwd and su, and adds a number of new features. Yes, still MORE new features ... Double sized passwords - This feature allows passwords up to 16 characters long. It is completely compatible with old 8 character passwords. Hushlogin behaves better - .hushlogin files now function like BSD. Both the mail status message and the last login information are suppressed. Previously only /etc/motd was canned. Configurable ERASE and KILL characters - login sets ERASE and KILL to configurable values. Handy for ancient systems which still use '#' and '@'. Configurable default ULIMIT and UMASK - Allows ULIMIT and UMASK to be set at login time without regenerating the kernel. Default may still be overriden by appropriate entries in the GECOS field. Console list may now be given - The CONSOLE option has been modified to allow a list of legal terminals to be provided. The list is present in a file with one name per entry. Bugs fixed - a64l() and l64a() are now included by using -DNEED_AL64. login now sets ISIG termio mode. passwd makes /etc/passwd readable if shadow isn't being used. passwd includes newline after updated entry always. su now execs shell more like prior su. su provides more secure paths by default. su gives correct user name if the requested one did not exist. sulogin determines correct tty name. *** Makefile --- new/Makefile ************** *** 1,5 # ! # @(#)Makefile 1.4 - System V shadow password system # # @(#)Makefile 1.4 18:06:16 2/20/89 # --- 1,5 ----- # ! # @(#)Makefile 1.5 - System V shadow password system # # @(#)Makefile 1.5 15:59:30 3/4/89 # ************** *** 1,7 # # @(#)Makefile 1.4 - System V shadow password system # ! # @(#)Makefile 1.4 18:06:16 2/20/89 # SHELL = /bin/sh --- 1,7 ----- # # @(#)Makefile 1.5 - System V shadow password system # ! # @(#)Makefile 1.5 15:59:30 3/4/89 # SHELL = /bin/sh # Uncomment the next line if you need fgetpwent() ************** *** 4,9 # @(#)Makefile 1.4 18:06:16 2/20/89 # SHELL = /bin/sh # Flags for SCO Xenix/386 CFLAGS = -O -M3 -g -DFGETPWENT --- 4,13 ----- # @(#)Makefile 1.5 15:59:30 3/4/89 # SHELL = /bin/sh + # Uncomment the next line if you need fgetpwent() + PWDEF = -DFGETPWENT + # Uncomment the next line if you need a64l() and l64a(). + AL64DEF = -DNEED_AL64 # Flags for SCO Xenix/386 CFLAGS = -O -M3 -g $(PWDEF) $(AL64DEF) ************** *** 6,12 SHELL = /bin/sh # Flags for SCO Xenix/386 ! CFLAGS = -O -M3 -g -DFGETPWENT LIBS = -lcrypt LDFLAGS = -M3 -g LTFLAGS = --- 10,16 ----- AL64DEF = -DNEED_AL64 # Flags for SCO Xenix/386 ! CFLAGS = -O -M3 -g $(PWDEF) $(AL64DEF) LIBS = -lcrypt LDFLAGS = -M3 -g LTFLAGS = ************** *** 12,18 LTFLAGS = # Flags for normal machines ! # CFLAGS = -O -g # LIBS = # LDFLAGS = -g --- 16,22 ----- LTFLAGS = # Flags for normal machines ! # CFLAGS = -O -g $(PWDEF) $(AL64DEF) # LIBS = # LDFLAGS = -g ************** *** 144,149 dialup.o: dialup.h dialchk.o: dialup.h config.h clean: -rm -f *.o a.out core npasswd nshadow --- 148,155 ----- dialup.o: dialup.h dialchk.o: dialup.h config.h + + valid.o: config.h clean: -rm -f *.o a.out core npasswd nshadow *** README --- new/README ************** *** 16,22 for the maintenance of this software package. The author is under no obligation to provide modifications or improvements. ! Begin by reading and editting the config.h file. All options are selected by using #define's. A brief description for each available option appears below. --- 16,22 ----- for the maintenance of this software package. The author is under no obligation to provide modifications or improvements. ! Begin by reading and editing the config.h file. All options are selected by using #define's. A brief description for each available option appears below. ************** *** 20,26 by using #define's. A brief description for each available option appears below. ! Note that there are MANY options. Dialup Password Files - This option permits individual ports to have an additional --- 20,28 ----- by using #define's. A brief description for each available option appears below. ! Note that there are MANY options. As distributed all options are turned ! on, which produces a really nice package. This is the system as used on ! the authors machine. Dialup Password Files - This option permits individual ports to have an additional ************** *** 38,43 Select this option by defining the SHADOWPWD macro. Obscure Password Testing - This option includes code to test user passwords for complexity. The programmer is encouraged to edit the --- 40,52 ----- Select this option by defining the SHADOWPWD macro. + Double Length Passwords - + This option extends the maximum length of a user password + to 16 characters from eight. + + Select this option by defining the DOUBLESIZE macro. + Credit for this option is due Jonathan Bayer. + Obscure Password Testing - This option includes code to test user passwords for complexity. The programmer is encouraged to edit the ************** *** 97,103 account. Select this option by defining the CONSOLE macro to ! have the desired port name. Message of the Day Printing - This option causes the message of the day to be --- 106,114 ----- account. Select this option by defining the CONSOLE macro to ! have the desired port name. If this file is a regular ! file, it is considered to contain a list of legal port ! names, one per line. Message of the Day Printing - This option causes the message of the day to be ************** *** 136,142 Select this option by defining the TTYTYPE macro as having the value of the name of the type to port ! mapping file. File Size Setting - This option includes code to set the user's ulimit --- 147,154 ----- Select this option by defining the TTYTYPE macro as having the value of the name of the type to port ! mapping file. Credit for this option is due Chip ! Rosenthal. File Size Setting - This option includes code to set the user's ulimit ************** *** 154,156 Select this option by defining the SULOG macro to have the value of the name of the file you want attempts logged to. --- 166,190 ----- Select this option by defining the SULOG macro to have the value of the name of the file you want attempts logged to. + + Configurable Editing Keys - + This options allows the erase and kill characters to + be selected. A default value is provided. By default + ERASE will be ^H and KILL will be ^U. + + Select this option by defining the ERASECHAR macro + to be the desired erase character and the KILLCHAR + macro to be the desired KILL character. + + Default ulimit and umask Values - + This option allows you to select the default values + for ulimit and umask, allowing you to avoid + regenerating your system kernel. These values may be + overriden with appropriate entries in the GECOS field. + + Select the default ulimit by defining the ULIMIT + macro, and the default umask by defining the UMASK + macro. + + Warning: These values will not apply to processes + executed by /etc/cron or any of their children. *** age.c --- new/age.c ************** *** 4,10 #include "config.h" #ifndef lint ! static char _sccsid[] = "@(#)age.c 1.2 08:41:03 2/22/89"; #endif #ifndef PASSWD --- 4,10 ----- #include "config.h" #ifndef lint ! static char _sccsid[] = "@(#)age.c 1.3 15:59:36 3/4/89"; #endif #ifndef PASSWD ************** *** 36,41 #ifdef AGING #ifdef PASSWD char *l64a (l) long l; { --- 36,42 ----- #ifdef AGING #ifdef PASSWD + #ifdef NEED_AL64 char *l64a (l) long l; { ************** *** 53,58 return (buf); } #endif int i64c (i) int i; { --- 54,60 ----- return (buf); } #endif + #endif int i64c (i) int i; { ************** *** 79,84 return ('\0'); } long a64l (s) char *s; { --- 81,87 ----- return ('\0'); } + #ifdef NEED_AL64 long a64l (s) char *s; { ************** *** 92,97 } return (value); } #ifndef PASSWD void expire (age) char *age; --- 95,101 ----- } return (value); } + #endif #ifndef PASSWD void expire (age) char *age; *** config.h --- new/config.h ************** *** 1,7 /* * Configuration file for login. * ! * @(#)config.h 1.2 18:06:19 2/20/89 */ /* --- 1,7 ----- /* * Configuration file for login. * ! * @(#)config.h 1.3 15:59:38 3/4/89 */ /* ************** *** 17,23 #define SHADOWPWD /* ! * Define OBSCURE to include hard password testing code. */ #define OBSCURE --- 17,23 ----- #define SHADOWPWD /* ! * Define DOUBLESIZE to use 16 character passwords */ #define DOUBLESIZE ************** *** 20,25 * Define OBSCURE to include hard password testing code. */ #define OBSCURE /* --- 20,31 ----- * Define DOUBLESIZE to use 16 character passwords */ + #define DOUBLESIZE + + /* + * Define OBSCURE to include hard password testing code. + */ + #define OBSCURE /* ************** *** 54,60 /* * Define the default PATH and SUPATH here. PATH is for non-privileged ! * users, SUPATH is for root. */ #define PATH "PATH=:/bin:/usr/bin" --- 60,67 ----- /* * Define the default PATH and SUPATH here. PATH is for non-privileged ! * users, SUPATH is for root. The first pair are for real trusting ! * systems, the second pair are for the paranoid ... */ /* #define PATH "PATH=:/bin:/usr/bin" */ ************** *** 57,64 * users, SUPATH is for root. */ ! #define PATH "PATH=:/bin:/usr/bin" ! #define SUPATH "PATH=:/bin:/usr/bin:/etc" /* * Define the mailbox directory --- 64,73 ----- * systems, the second pair are for the paranoid ... */ ! /* #define PATH "PATH=:/bin:/usr/bin" */ ! /* #define SUPATH "PATH=:/bin:/usr/bin:/etc" */ ! #define PATH "PATH=/bin:/usr/bin" ! #define SUPATH "PATH=/bin:/usr/bin:/etc" /* * Define the mailbox directory ************** *** 82,88 #define MAILCHECK /* ! * Define CONSOLE if you want ROOT restricted to a single terminal */ #define CONSOLE "tty01" --- 91,101 ----- #define MAILCHECK /* ! * Define CONSOLE if you want ROOT restricted to a particular terminal. ! * ! * Use the name of the tty line if you only want a single line, or use ! * the name of the file containing the permissible ports if you wish to ! * allow root logins on more than one port. */ /* #define CONSOLE "console" /* root on /dev/console only */ ************** *** 85,91 * Define CONSOLE if you want ROOT restricted to a single terminal */ ! #define CONSOLE "tty01" /* * Define MOTD if you want the message of the day (/etc/motd) printed --- 98,105 ----- * allow root logins on more than one port. */ ! /* #define CONSOLE "console" /* root on /dev/console only */ ! #define CONSOLE "/etc/consoles" /* check /etc/consoles for a list */ /* * Define MOTD if you want the message of the day (/etc/motd) printed ************** *** 97,103 /* * Define HUSHLOGIN if you want the code added to avoid printing the * motd if a file $HOME/.hushlogin exists. This obviously only matters ! * if MOTD is #define'd. */ #define HUSHLOGIN --- 111,117 ----- /* * Define HUSHLOGIN if you want the code added to avoid printing the * motd if a file $HOME/.hushlogin exists. This obviously only matters ! * if any of MOTD, MAILCHECK or LASTLOG are #define'd. */ #define HUSHLOGIN ************** *** 150,152 */ #define PWDLOCK "/etc/.pwdlock" --- 164,179 ----- */ #define PWDLOCK "/etc/.pwdlock" + + /* + * Wierd stuff follows ... + * + * The following macros exist solely to override stuff ... + * You will probably want to change their values to suit your + * fancy. + */ + + #define ERASECHAR '\b' + #define KILLCHAR '\025' + #define UMASK 022 + #define ULIMIT (1L<<20) *** lmain.c --- new/lmain.c ************** *** 1,4 #include <sys/types.h> #include <stdio.h> #include <pwd.h> #include <utmp.h> --- 1,5 ----- #include <sys/types.h> + #include <sys/stat.h> #include <stdio.h> #include <pwd.h> #include <utmp.h> ************** *** 5,10 #include <time.h> #include <string.h> #include <signal.h> #include "config.h" #include "lastlog.h" --- 6,12 ----- #include <time.h> #include <string.h> #include <signal.h> + #include <termio.h> #include "config.h" #include "lastlog.h" ************** *** 9,15 #include "lastlog.h" #ifndef lint ! static char _sccsid[] = "@(#)lmain.c 1.3 18:06:20 2/20/89"; #endif char name[BUFSIZ]; --- 11,17 ----- #include "lastlog.h" #ifndef lint ! static char _sccsid[] = "@(#)lmain.c 1.4 15:59:41 3/4/89"; #endif #ifndef ERASECHAR ************** *** 12,17 static char _sccsid[] = "@(#)lmain.c 1.3 18:06:20 2/20/89"; #endif char name[BUFSIZ]; char pass[BUFSIZ]; char home[BUFSIZ]; --- 14,27 ----- static char _sccsid[] = "@(#)lmain.c 1.4 15:59:41 3/4/89"; #endif + #ifndef ERASECHAR + #define ERASECHAR '\b' /* backspace */ + #endif + + #ifndef KILLCHAR + #define KILLCHAR '\025' /* control U */ + #endif + char name[BUFSIZ]; char pass[BUFSIZ]; char home[BUFSIZ]; ************** *** 17,22 char home[BUFSIZ]; char prog[BUFSIZ]; char mail[BUFSIZ]; struct passwd pwent; struct utmp utent; --- 27,36 ----- char home[BUFSIZ]; char prog[BUFSIZ]; char mail[BUFSIZ]; + #ifdef HUSHLOGIN + char hush[BUFSIZ]; + int hushed; + #endif struct passwd pwent; struct utmp utent; ************** *** 21,26 struct passwd pwent; struct utmp utent; struct lastlog lastlog; #ifndef MAXENV #define MAXENV 64 --- 35,41 ----- struct passwd pwent; struct utmp utent; struct lastlog lastlog; + struct termio termio; #ifndef MAXENV #define MAXENV 64 ************** *** 62,67 char **envp; { int retries = RETRIES; checkutmp (); /* must be lowest level shell */ --- 77,88 ----- char **envp; { int retries = RETRIES; + #ifdef CONSOLE + int conflag; + char console[BUFSIZ]; + FILE *fp; + struct stat statbuf; + #endif checkutmp (); /* must be lowest level shell */ ************** *** 68,73 if (! isatty (0)) /* must be a terminal */ exit (1); while (*envp) /* add inherited environment, */ addenv (*envp++); /* some variables change later */ --- 89,112 ----- if (! isatty (0)) /* must be a terminal */ exit (1); + (void) ioctl (0, TCGETA, &termio); /* get terminal characteristics */ + + /* + * Add your favorite terminal modes here ... + */ + + termio.c_cflag |= ISIG; + + termio.c_cc[VERASE] = ERASECHAR; + termio.c_cc[VKILL] = KILLCHAR; + (void) ioctl (0, TCSETAF, &termio); /* set erase and kill characters */ + + #ifdef UMASK + umask (UMASK); /* override the default umask */ + #endif + #ifdef ULIMIT + ulimit (2, (long) ULIMIT); /* override the default ulimit */ + #endif while (*envp) /* add inherited environment, */ addenv (*envp++); /* some variables change later */ ************** *** 132,140 setutmp (); /* make entry in utmp & wtmp files */ #ifdef CONSOLE ! if (pwent.pw_uid == 0 && /* root no logging in on console ? */ ! strncmp (CONSOLE, utent.ut_line, sizeof utent.ut_line)) ! exit (1); /* then exit! */ #endif if (pwent.pw_shell && pwent.pw_shell[0] == '*') /* subsystem root */ subsystem (); /* figure out what to execute */ --- 171,193 ----- setutmp (); /* make entry in utmp & wtmp files */ #ifdef CONSOLE ! if (pwent.pw_uid == 0 && stat (CONSOLE, &statbuf) == 0) { ! if ((statbuf.st_mode & S_IFMT) == S_IFREG) { ! fp = fopen (CONSOLE, "r"); ! while (fp && fgets (console, BUFSIZ, fp) == console) { ! console[strlen (console) - 1] = '\0'; ! if (strcmp (console, utent.ut_line) == 0) ! break; ! } ! if (! fp || feof (fp)) ! exit (1); /* found EOF before tty line */ ! ! fclose (fp); ! } else { ! if (strcmp (CONSOLE, utent.ut_line) != 0) ! exit (1); ! } ! } #endif if (pwent.pw_shell && pwent.pw_shell[0] == '*') /* subsystem root */ subsystem (); /* figure out what to execute */ ************** *** 147,152 if (pwent.pw_age) /* check for age of password ... */ expire (pwent.pw_age); /* ... ask for new one if expired */ #endif #ifdef MOTD motd (); /* print the message of the day */ #endif --- 200,209 ----- if (pwent.pw_age) /* check for age of password ... */ expire (pwent.pw_age); /* ... ask for new one if expired */ #endif + #ifdef HUSHLOGIN + sprintf (hush, "%s/.hushlogin", strchr (home, '=') + 1); + hushed = access (hush, 0) != -1; + #endif #ifdef MOTD motd (); /* print the message of the day */ #endif ************** *** 151,157 motd (); /* print the message of the day */ #endif #ifdef LASTLOG ! if (lastlog.ll_time != 0) printf ("Last login: %.19s on %s\n", ctime (&lastlog.ll_time), lastlog.ll_line); #endif --- 208,214 ----- motd (); /* print the message of the day */ #endif #ifdef LASTLOG ! if (lastlog.ll_time != 0 && ! hushed) printf ("Last login: %.19s on %s\n", ctime (&lastlog.ll_time), lastlog.ll_line); #endif *** login.1 --- new/login.1 ************** *** 56,61 Ulimit, umask and nice values may also be set according to entries in the GECOS field. .PP An initialization script for your command interpreter may also be executed. Please see the appropriate manual section for more information on --- 56,65 ----- Ulimit, umask and nice values may also be set according to entries in the GECOS field. .PP + On some installations, the environmental variable \fB$TERM\fR will be + initialize to the terminal type on your tty line, as specified in + \fI/etc/ttytype\fR. + .PP An initialization script for your command interpreter may also be executed. Please see the appropriate manual section for more information on ************** *** 74,79 /etc/shadow \- encrypted passwords and age information .br /etc/motd \- system message file .br $HOME/.profile \- initialization script for default shell .br --- 78,85 ----- /etc/shadow \- encrypted passwords and age information .br /etc/motd \- system message file + .br + /etc/ttytype \- list of terminal types .br $HOME/.profile \- initialization script for default shell .br *** mail.c --- new/mail.c ************** *** 3,9 #include <string.h> #include "config.h" ! extern char mail[]; #ifdef MAILCHECK void mailcheck () --- 3,11 ----- #include <string.h> #include "config.h" ! #ifndef lint ! static char _sccsid[] = "@(#)mail.c 1.2 15:59:47 3/4/89"; ! #endif extern char mail[]; ************** *** 5,10 extern char mail[]; #ifdef MAILCHECK void mailcheck () { --- 7,18 ----- static char _sccsid[] = "@(#)mail.c 1.2 15:59:47 3/4/89"; #endif + extern char mail[]; + + #ifdef HUSHLOGIN + extern int hushed; + #endif + #ifdef MAILCHECK void mailcheck () { ************** *** 11,16 struct stat statbuf; char *mailbox; if (mailbox = strchr (mail, '=')) mailbox++; else --- 19,28 ----- struct stat statbuf; char *mailbox; + #ifdef HUSHLOGIN + if (hushed) + return; + #endif if (mailbox = strchr (mail, '=')) mailbox++; else *** motd.c --- new/motd.c ************** *** 2,8 #include <string.h> #include "config.h" ! extern char home[]; void motd () { --- 2,10 ----- #include <string.h> #include "config.h" ! #ifndef lint ! static char _sccsid[] = "@(#)motd.c 1.2 15:59:49 3/4/89"; ! #endif extern char home[]; #ifdef HUSHLOGIN ************** *** 4,9 extern char home[]; void motd () { #ifdef MOTD --- 6,17 ----- static char _sccsid[] = "@(#)motd.c 1.2 15:59:49 3/4/89"; #endif + extern char home[]; + #ifdef HUSHLOGIN + extern int hushed; + #endif + + #ifdef MOTD void motd () { FILE *fp; ************** *** 6,12 void motd () { - #ifdef MOTD FILE *fp; register int c; #ifdef HUSHLOGIN --- 14,19 ----- #ifdef MOTD void motd () { FILE *fp; register int c; ************** *** 9,16 #ifdef MOTD FILE *fp; register int c; - #ifdef HUSHLOGIN - char hush[BUFSIZ]; (void) strcat (strcpy (hush, home + 5), "/.hushlogin"); --- 16,21 ----- { FILE *fp; register int c; #ifdef HUSHLOGIN if (hushed) ************** *** 12,20 #ifdef HUSHLOGIN char hush[BUFSIZ]; ! (void) strcat (strcpy (hush, home + 5), "/.hushlogin"); ! ! if (access (hush, 0) == 0) return; #endif if ((fp = fopen ("/etc/motd", "r")) == (FILE *) 0) --- 17,24 ----- FILE *fp; register int c; ! #ifdef HUSHLOGIN ! if (hushed) return; #endif if ((fp = fopen ("/etc/motd", "r")) == (FILE *) 0) ************** *** 25,29 fclose (fp); fflush (stdout); - #endif } --- 29,33 ----- fclose (fp); fflush (stdout); } #endif ************** *** 27,29 fflush (stdout); #endif } --- 30,33 ----- fclose (fp); fflush (stdout); } + #endif *** password.c --- new/password.c ************** *** 9,15 * Need to fake up getpass(). Returns TRUE if a password * was successfully input, and FALSE otherwise, including * EOF on input or ioctl() failure. pass is not modified ! * on failure. */ #ifndef lint --- 9,16 ----- * Need to fake up getpass(). Returns TRUE if a password * was successfully input, and FALSE otherwise, including * EOF on input or ioctl() failure. pass is not modified ! * on failure. The input length limit may be set by ! * changing the value of PASSLIMIT. */ #ifndef lint ************** *** 13,19 */ #ifndef lint ! static char _sccsid[] = "@(#)password.c 1.3 08:41:05 2/22/89"; #endif int password (prompt, pass) --- 14,20 ----- */ #ifndef lint ! static char _sccsid[] = "@(#)password.c 1.4 15:59:50 3/4/89"; #endif #define PASSLIMIT 20 ************** *** 16,21 static char _sccsid[] = "@(#)password.c 1.3 08:41:05 2/22/89"; #endif int password (prompt, pass) char *prompt; char *pass; --- 17,24 ----- static char _sccsid[] = "@(#)password.c 1.4 15:59:50 3/4/89"; #endif + #define PASSLIMIT 20 + int password (prompt, pass) char *prompt; char *pass; ************** *** 47,53 ioctl (fileno (fp), TCSETAF, &save); if (! eof) { ! buf[8] = '\0'; if ((cp = strchr (buf, '\n')) || (cp = strchr (buf, '\r'))) *cp = '\0'; --- 50,56 ----- ioctl (fileno (fp), TCSETAF, &save); if (! eof) { ! buf[PASSLIMIT] = '\0'; if ((cp = strchr (buf, '\n')) || (cp = strchr (buf, '\r'))) *cp = '\0'; *** pmain.c --- new/pmain.c ************** *** 14,20 #endif #ifndef lint ! static char _sccsid[] = "@(#)pmain.c 1.3 08:41:07 2/22/89"; #endif char name[BUFSIZ]; --- 14,20 ----- #endif #ifndef lint ! static char _sccsid[] = "@(#)pmain.c 1.4 15:59:52 3/4/89"; #endif char name[BUFSIZ]; ************** *** 63,68 FILE *pwd; char buf[BUFSIZ]; #endif argc--; argv++; /* shift ... */ --- 63,69 ----- FILE *pwd; char buf[BUFSIZ]; #endif + char tmp[BUFSIZ]; argc--; argv++; /* shift ... */ ************** *** 184,191 #endif (void) time (&salttime); salttime = ((salttime & 07777) ^ ((salttime >> 14) & 07777)) & 07777; ! pwent.pw_passwd = crypt (pass, l64a (salttime)); ! /* * Now we get to race the bad guy. I don't think he can get us. * --- 185,198 ----- #endif (void) time (&salttime); salttime = ((salttime & 07777) ^ ((salttime >> 14) & 07777)) & 07777; ! pwent.pw_passwd = tmp; ! strcpy (pwent.pw_passwd, crypt (pass, l64a (salttime))); ! #ifdef DOUBLESIZE ! if (strlen (pass) > 8) { ! strcpy (pwent.pw_passwd + 13, ! crypt (pass + 8, l64a (salttime)) + 2); ! } ! #endif /* * Now we get to race the bad guy. I don't think he can get us. * ************** *** 329,335 else (void) fprintf (npwd, "%s:", pwent.pw_passwd); ! (void) fprintf (npwd, "%d:%d:%s:%s:%s", pwent.pw_uid, pwent.pw_gid, pwent.pw_gecos, pwent.pw_dir, pwent.pw_shell ? pwent.pw_shell:""); --- 336,342 ----- else (void) fprintf (npwd, "%s:", pwent.pw_passwd); ! (void) fprintf (npwd, "%d:%d:%s:%s:%s\n", pwent.pw_uid, pwent.pw_gid, pwent.pw_gecos, pwent.pw_dir, pwent.pw_shell ? pwent.pw_shell:""); ************** *** 346,351 fflush (npwd); fclose (npwd); #ifdef NDEBUG if (unlink (OPWDFILE) == -1) { if (errno != ENOENT) { puts ("Can't unlink backup file"); --- 353,359 ----- fflush (npwd); fclose (npwd); #ifdef NDEBUG + chmod (NPWDFILE, 0644); if (unlink (OPWDFILE) == -1) { if (errno != ENOENT) { puts ("Can't unlink backup file"); *** smain.c --- new/smain.c ************** *** 7,13 #include "lastlog.h" #ifndef lint ! static char _sccsid[] = "@(#)smain.c 1.4 08:41:11 2/22/89"; #endif #ifndef MAXENV --- 7,13 ----- #include "lastlog.h" #ifndef lint ! static char _sccsid[] = "@(#)smain.c 1.5 15:59:55 3/4/89"; #endif #ifndef MAXENV ************** *** 22,27 #define SUPATH ":/bin:/usr/bin:/etc" #endif char name[BUFSIZ]; char pass[BUFSIZ]; char home[BUFSIZ]; --- 22,32 ----- #define SUPATH ":/bin:/usr/bin:/etc" #endif + #ifdef HUSHLOGIN + char hush[BUFSIZ]; + int hushed; + #endif + char name[BUFSIZ]; char pass[BUFSIZ]; char home[BUFSIZ]; ************** *** 50,55 char **envp; { char *getenv (); int doshell; int fakelogin = 0; int amroot; --- 55,61 ----- char **envp; { char *getenv (); + char *cp; int doshell; int fakelogin = 0; int amroot; ************** *** 92,98 pwent.pw_shell = "/bin/sh"; if (pwent.pw_name == (char *) 0) { /* unknown user */ ! (void) fprintf (stderr, "Unknown id: %s\n", pwent.pw_name); exit (1); } --- 98,104 ----- pwent.pw_shell = "/bin/sh"; if (pwent.pw_name == (char *) 0) { /* unknown user */ ! (void) fprintf (stderr, "Unknown id: %s\n", name); exit (1); } ************** *** 144,149 } } if (! doshell) { /* execute arguments as command */ argv[-1] = pwent.pw_shell; (void) execv (pwent.pw_shell, &argv[-1]); (void) fprintf (stderr, "No shell\n"); --- 150,157 ----- } } if (! doshell) { /* execute arguments as command */ + if (cp = getenv ("SHELL")) + pwent.pw_shell = cp; argv[-1] = pwent.pw_shell; (void) execv (pwent.pw_shell, &argv[-1]); (void) fprintf (stderr, "No shell\n"); ************** *** 150,155 exit (1); } if (fakelogin) { #ifdef MOTD motd (); /* print the message of the day */ #endif --- 158,167 ----- exit (1); } if (fakelogin) { + #ifdef HUSHLOGIN + sprintf (hush, "%s/.hushlogin", strchr (home, '=') + 1); + hushed = access (hush, 0) != -1; + #endif #ifdef MOTD motd (); /* print the message of the day */ #endif ************** *** 158,164 #endif shell (pwent.pw_shell); /* exec the shell finally. */ } else { ! execl (pwent.pw_shell, "su", (char *) 0); perror (pwent.pw_shell); exit (1); } --- 170,181 ----- #endif shell (pwent.pw_shell); /* exec the shell finally. */ } else { ! if (cp = strrchr (pwent.pw_shell, '/')) ! cp++; ! else ! cp = pwent.pw_shell; ! ! execl (pwent.pw_shell, cp, (char *) 0); perror (pwent.pw_shell); exit (1); } *** su.1 --- new/su.1 ************** *** 18,23 In particular, an argument of \fB-c\fR will cause the next argument to be treated as a command by most command interpreters. .PP The user will be prompted for a password, if appropriate. Invalid passwords will produce an error message. --- 18,26 ----- In particular, an argument of \fB-c\fR will cause the next argument to be treated as a command by most command interpreters. + The command will be executed under the shell specified by + \fB$SHELL\fR, or if undefined, by the one specified in + \fI/etc/passwd\fR. .PP The user will be prompted for a password, if appropriate. Invalid passwords will produce an error message. *** sulogin.c --- new/sulogin.c ************** *** 2,7 #include <stdio.h> #include <pwd.h> #include <utmp.h> #include "config.h" #include "lastlog.h" --- 2,8 ----- #include <stdio.h> #include <pwd.h> #include <utmp.h> + #include <string.h> #include "config.h" #include "lastlog.h" ************** *** 5,10 #include "config.h" #include "lastlog.h" char name[BUFSIZ]; char pass[BUFSIZ]; char home[BUFSIZ]; --- 6,15 ----- #include "config.h" #include "lastlog.h" + #ifndef lint + static char _sccsid[] = "@(#)sulogin.c 1.2 15:59:59 3/4/89"; + #endif + char name[BUFSIZ]; char pass[BUFSIZ]; char home[BUFSIZ]; ************** *** 96,104 * ownership. */ ! if (cp = ttyname (0)) /* found entry in /dev/ */ ! strcpy (utent.ut_line, cp); /* needed for tty perms (setup) */ ! if (getenv ("IFS")) /* don't export user IFS ... */ addenv ("IFS= \t\n"); /* ... instead, set a safe IFS */ --- 101,112 ----- * ownership. */ ! if (cp = ttyname (0)) { /* found entry in /dev/ */ ! if (strrchr (cp, '/') != (char *) 0) ! strcpy (utent.ut_line, strrchr (cp, '/') + 1); ! else ! strcpy (utent.ut_line, cp); ! } if (getenv ("IFS")) /* don't export user IFS ... */ addenv ("IFS= \t\n"); /* ... instead, set a safe IFS */ *** valid.c --- new/valid.c ************** *** 1,3 #include <pwd.h> /* --- 1,4 ----- + #include <stdio.h> #include <pwd.h> #include <string.h> #include "config.h" ************** *** 1,4 #include <pwd.h> /* * valid - compare encrypted passwords --- 1,7 ----- #include <stdio.h> #include <pwd.h> + #include <string.h> + #include "config.h" #ifndef lint static char _sccsid[] = "@(#)valid.c 1.2 16:00:01 3/4/89"; ************** *** 1,5 #include <pwd.h> /* * valid - compare encrypted passwords * --- 3,12 ----- #include <string.h> #include "config.h" + #ifndef lint + static char _sccsid[] = "@(#)valid.c 1.2 16:00:01 3/4/89"; + #endif + /* * valid - compare encrypted passwords * ************** *** 15,20 char *encrypt; char *salt; char *crypt (); /* * Start with blank or empty password entries. Always encrypt --- 22,31 ----- char *encrypt; char *salt; char *crypt (); + #ifdef DOUBLESIZE + int firsthalf; + int longpass; + #endif /* * Start with blank or empty password entries. Always encrypt ************** *** 32,37 return (0); /* user entered something! */ } /* * If there is no entry then we need a salt to use. */ --- 43,52 ----- return (0); /* user entered something! */ } + #ifdef DOUBLESIZE + longpass = entry->pw_passwd && strlen (entry->pw_passwd) > 13; + #endif + /* * /* ************** *** 33,38 } /* * If there is no entry then we need a salt to use. */ --- 48,55 ----- #endif /* + * + /* * If there is no entry then we need a salt to use. */ ************** *** 49,54 */ encrypt = crypt (password, salt); /* * One last time we must deal with there being no password file --- 66,74 ----- */ encrypt = crypt (password, salt); + #ifdef DOUBLESIZE + firsthalf = entry->pw_passwd + && strncmp (encrypt + 2, entry->pw_passwd + 2, 11) == 0; if (strlen (password) > 8) encrypt = crypt (password + 8, salt); ************** *** 50,55 encrypt = crypt (password, salt); /* * One last time we must deal with there being no password file * entry for the user. We use the pw_passwd == NULL idiom to --- 70,82 ----- firsthalf = entry->pw_passwd && strncmp (encrypt + 2, entry->pw_passwd + 2, 11) == 0; + if (strlen (password) > 8) + encrypt = crypt (password + 8, salt); + else { + (void) crypt (password, salt); /* waste time ... */ + encrypt = ""; + } + #endif /* * One last time we must deal with there being no password file * entry for the user. We use the pw_passwd == NULL idiom to ************** *** 59,65 * with the salt, which is "xx", not "". */ if (entry->pw_passwd && strcmp (encrypt, entry->pw_passwd) == 0) return (1); else return (0); --- 86,93 ----- * with the salt, which is "xx", not "". */ + #ifndef DOUBLESIZE if (entry->pw_passwd && strcmp (encrypt, entry->pw_passwd) == 0) return (1); else return (0); ************** *** 63,66 return (1); else return (0); } --- 91,104 ----- return (1); else return (0); + #else + if (! longpass) + return (firsthalf); + + if (entry->pw_passwd && firsthalf + && strncmp (encrypt + 2, entry->pw_passwd + 13) == 0) + return (1); + else + return (0); + #endif } -- John F. Haugh II +--Quote of the Week:------------------ VoiceNet: (214) 250-3311 Data: -6272 | "Give me your poor huddled masses, InterNet: jfh@rpp386.Dallas.TX.US | Let's club 'em to death ..." UucpNet : <backbone>!killer!rpp386!jfh +--------------------------------------