Shadow Login Suite, version 3 (part 1 of 8)
John F Haugh II
jfh at rpp386.cactus.org
Fri May 17 02:31:22 AEST 1991
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# README
# newgrp.c
# Makefile
# config.h
# pwunconv.c
# obscure.c
# age.c
# This archive created: Sun Mar 3 13:27:13 1991
# By: John F Haugh II (River Parishes Programming, Austin TX)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'README'" '(12725 characters)'
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
XThis is the explanatory document for John F. Haugh II's login replacement,
Xrelease 3. This document was last updated 11/21/90.
X
XThis software is copyright 1988, 1989, 1990, John F. Haugh II. All rights
Xreserved. Use, duplication and disclosure is permitted according to the
Xguidelines listed below.
X
XThis software is being provided as a freely redistributable login clone.
XYou may distribute this software provided you do not charge for other than
Xtransmission costs. You are free to copy this software provided you
Xdo not restrict the rights of the recipients to further copy this software.
X
XTHIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL
XLIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE
XFOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO
XOBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS
XENCOURAGE TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL
XLOSS OF INFORMATION OR MACHINE RESOURCES.
X
XSpecial thanks are due to Chip Rosenthal for his fine testing efforts;
Xto Steve Simmons for his work in porting this code to BSD; and to Bill
XKennedy for his contributions of LaserJet printer time and energies.
XAlso, thanks for Dennis L. Mumaugh for the initial shadow password
Xinformation and to Tony Walton (olapw at olgb1.oliv.co.uk) for the System
XV Release 4 changes.
X
XNew for Release 3:
X The objects are being combined into libraries to make maintenance
X easier and to encourage developers to use the modules as the
X basis for new tools.
X
X New lint rules have been added to make the code easier to lint.
X
XBegin by reading and editing the config.h file. All options are selected
Xby using #define's. A brief description for each available option appears
Xbelow. You may want to print this file out as it is LONG and you will
Xneed to refer to it while editting config.h. You will also have to edit
Xthe Makefile. The possible differences are documented there. Pay close
Xattention to the install: rule. DO NOT MAIL ME DIFFERENCES FOR VARIOUS
XINSTALLATION PROBLEMS. If you must share your experiences, do so on the
Xnet. Login now runs on about 30 different varieties of UNIX that I have
Xbeen made aware of.
X
XNote that there are MANY options. As distributed most options are turned
Xon, which produces a really nice package. This is the system as used on
Xsome of the authors' machines.
X
XDialup Password Files -
X This option permits individual ports to have an additional
X password prompted for on a by-shell basis. /etc/dialups
X contains a list of dialup ports, d_passwd contains the
X password for each shell requiring a dialup password.
X
X Select this option by defining the DIALUP macro.
X
XPort Access Times File -
X This option permits individual ports to have restrictions
X based on user name and time of day and week.
X
X Select this option by defining the PORTTIME macro.
X
XShadow [ unreadable ] Password Files -
X This option utilizes an alternate, non-readable file to
X contain the actual encrypted passwords. This is presumed
X to increase system security by increasing the difficulty
X with which system crackers obtain encrypted passwords.
X
X Select this option by defining the SHADOWPWD macro.
X
XDBM Password Files -
X This option utilizes the DBM database access routines to
X increase the performance of user name and ID lookups in the
X password file.
X
X Select this option by defining both the DBM and GETPWENT
X macros. The FGETPWENT macro must also be defined or the
X fgetpwent() library routine must be present.
X
XDouble Length Passwords -
X This option extends the maximum length of a user password
X to 16 characters from eight.
X
X Select this option by defining the DOUBLESIZE macro.
X Credit for this option is due Jonathan Bayer.
X
XObscure Password Testing -
X This option includes code to test user passwords for
X complexity. The programmer is encouraged to edit the
X file obscure.c to add additional methods for detecting
X simplistic passwords.
X
X Select this option by defining the OBSCURE macro.
X
X Additionally, the PASSLENGTH macro must be defined to
X control the minimum length for a legal password.
X
XMandatory Password Prompting -
X This option requires all passwords, including null ones,
X to be prompted for. Traditionally an account with a
X password field of '::' does not require prompting for.
X This option modifies this behavior to require even
X null passwords be prompted for.
X
X Select this option by defining the NOBLANK macro.
X
XPassword Aging Defaults -
X You may select the default number of days during which a
X password is valid. The pwconv command adds aging
X information to accounts which do not include it already.
X
X The MINDAYS macro must be defined to be the minimum
X number of days which must pass before a password may be
X changed. The MAXDAYS macro must be defined to be the
X maximum number of days which a password will remain
X valid during.
X
X The WARNDAYS macro controls how many days warning a user
X is given that their password is about to expire. The
X default is 10.
X
XHZ Environmental Variable -
X This option pre-defines the HZ environmental variable.
X Certain systems require this variable be defined for
X system time reporting functions to work properly.
X
X Select this option by defining the HZ macro to have
X the desired environmental variable value.
X
XTZ Environmental Variable -
X This option pre-defines the TZ environmental variable.
X This provides a default timezone variable for use by
X various utilities.
X
X Select this option by defining the TZ macro to have
X the desired environmental variable value, or the name
X of the file containing the desired value.
X
XPassword Aging -
X This option includes code to perform password aging.
X Password aging is presumed to increase system security
X by forcing users to change passwords on a regular
X basis. The resolution on password age is in weeks for
X non-shadow password systems and in days otherwise.
X
X Select this option by defining the AGING macro.
X
XMailbox Checking -
X This option includes code to check the status of the
X user's mailbox. One of three messages are produced
X depending on the status of the user's mailbox.
X
X Select this option by defining the MAILCHECK macro.
X
XConsole Restricted Root Logins -
X This option restricts the port which root may legally
X login on. This option presumably increases system
X security by preventing outside attacks against the root
X account.
X
X Select this option by defining the CONSOLE macro to
X have the desired port name. If this file is a regular
X file, it is considered to contain a list of legal port
X names, one per line. Note that the port names DO NOT
X begin with "/dev/" and that a file name would have to
X be fully qualified. See config.h for a pair of
X examples.
X
XRestricted User Logins -
X This option permits you to specify a file which disables
X user logins. This options permits you to keep normal
X users off of the system while performing maintenance
X functions.
X
X Select this option by defining NOLOGINS to be the name
X of the file to use.
X
XRestricted Use Accounts -
X This option permits certain accounts to be used for
X identification purposes only. This options associates
X login ID's with UID's, such as for disk space accounting
X or anonymous FTP accounts. Passwords for these accounts
X may only be changed by root.
X
X Select this option by defining NOUSE to be the string
X to include in the password file in place of the user's
X shell.
X
XMessage of the Day Printing -
X This option causes the message of the day to be
X printed at login time.
X
X Select this option by defining the MOTD macro.
X
X If you wish this feature to be overriden on a per-user
X basis, define the macro HUSHLOGIN and users may then
X turn off the /etc/motd message by creating a file
X '.hushlogin' in their home directories.
X
XLast Login Time Logging -
X This option causes a record to be made of successful
X logins in /usr/adm/lastlog. The format of the
X structure is defined in lastlog.h.
X
X Select this option by defining the LASTLOG macro.
X
X You will need to determine if you system already has
X a lastlog.h file and use that file if present.
X
XFailed Login Logging -
X This option causes a record to be kept of the most
X recent login failure by date and port. A cummulative
X count of failures is maintained and compared against
X an allowable limit.
X
X Select this option by defining the FAILLOG macro.
X
X An additional option is provided which will create
X utmp-like entries for each failed login. Because of
X security concerns, only valid account names will be
X logged.
X
X Select this option by defining the FTMP macro to be
X the name of a utmp-like file. You may control the
X recording of unknown login names by defining the
X UNKNOWNS macro. This prevents possible passwords from
X being entered into the FTMP file.
X
X See the file faillog.h and config.h for more details.
X
XTerminal Permissions -
X This option allows the terminal modes to be set at
X login time. This is particularly useful to disable
X messages on user's terminals.
X
X Select this option by defining the TTYPERM macro as
X having the desired mode.
X
XTerminal Type Setup -
X This option allows the terminal type to be set at
X login time. The environmental variable TERM will be
X set from the specified terminal to port mapping
X file.
X
X Select this option by defining the TTYTYPE macro as
X having the value of the name of the type to port
X mapping file. Credit for this option is due Chip
X Rosenthal.
X
XFile Size Setting -
X This option includes code to set the user's ulimit
X at login time. Additional code to set the umask and
X nice value is also included.
X
X Select this option by defining the QUOTAS macro.
X
XSwitch-User Logging -
X This option causes su(1) to log attempts to switch
X users. Su(1) will log all attempt, giving the old
X and new user ID's, tty port, and time. It also
X indicates if the attempt was successful.
X
X Select this option by defining the SULOG macro to
X have the value of the name of the file you want
X attempts logged to.
X
XConfigurable Editing Keys -
X This options allows the erase and kill characters to
X be selected. A default value is provided. By default
X ERASE will be ^H and KILL will be ^U.
X
X Select this option by defining the ERASECHAR macro
X to be the desired erase character and the KILLCHAR
X macro to be the desired KILL character.
X
XDefault ulimit and umask Values -
X This option allows you to select the default values
X for ulimit and umask, allowing you to avoid
X regenerating your system kernel. These values may be
X overriden with appropriate entries in the GECOS field.
X
X Select the default ulimit by defining the ULIMIT
X macro, and the default umask by defining the UMASK
X macro.
X
X Warning: These values will not apply to processes
X executed by /etc/cron or any of their children.
X
XBSD Notes: Steve Simmons scs at iti.org
X
XThe full port of the shadow package to BSD is not complete; but some
Xof the issues have been worked out. These notes describe the current
Xstate of things:
X
XIn order to make use of password aging under BSD, minor changes to
X/usr/include/pwd.h and getpwent() are needed. These changes are to
Xkeep the password age from messing up the encrypted password when not
Xusing shadow passwords, and involve placing a new field in the password
Xdata structure. To use this, you should apply the following two patches:
X pwd.h.patch
X getpwent.c.patch
Xto the BSD /usr/include/pwd.h and /usr/src/lib/libc/gen/getpwent.c,
Xrespectively. After applying the patches, rebuild your standard C
Xlibrary with the new getpwent. Programs which use the old getpwent
Xwill fail on password checking if they do a strcmp rather than a strncmp.
X[ I do not seem to have these two patches. I have provided an entire
Xgetpwent collection of code which may be useful instead. This code
Xdoes not support Sun Yellow Pages(tm?), which is a shame. -jfh ]
X
XThese changes are based on BSD4.3, not Tahoe
X
XToDo BSD:
X
XI'm working on this in my copious spare time (hah!); any help would
Xbe appreciated. If you decide to help, do these independantly rather
Xthan rework BSD code! Keep it redistributable!
X
XNo dbm functions have been put in place. Dbm functionality is needed
Xfor both /etc/password and /etc/shadow management. [ It is now possible
Xto create /etc/passwd.dir and /etc/passwd.pag using the new mkpasswd
Xcommand. getpwuid and getpwnam both use these files. Also, the
Xcommands chfn, chsh, and chage all update the DBM files. -jfh ]
X
XThe BSD GECOS field gets used for lots more stuff than the USG. At a
Xminimum this functionality should be duplicated under BSD; better is to put
Xit into USG as well; still better would be to make the chfn command for
Xboth systems; best would be site-configurable data to be put into GECOS/chfn.
X[ this is now possible using chfn and the -o option. - jfh ]
SHAR_EOF
if test 12725 -ne "`wc -c < 'README'`"
then
echo shar: "error transmitting 'README'" '(should have been 12725 characters)'
fi
fi
echo shar: "extracting 'newgrp.c'" '(8576 characters)'
if test -f 'newgrp.c'
then
echo shar: "will not over-write existing file 'newgrp.c'"
else
sed 's/^X//' << \SHAR_EOF > 'newgrp.c'
X/*
X * Copyright 1990, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#include <sys/types.h>
X#include <string.h>
X#include <stdio.h>
X#include <grp.h>
X#include "pwd.h"
X#include <termio.h>
X#ifdef SYS3
X#include <sys/ioctl.h>
X#endif
X#include "config.h"
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)newgrp.c 3.3 12:30:58 12/12/90";
X#endif
X
X#ifdef NGROUPS
Xint ngroups;
Xgid_t groups[NGROUPS];
X#endif
X
Xstruct passwd *pwd;
Xstruct passwd *getpwuid();
Xstruct passwd *getpwnam();
X
X#ifdef SHADOWPWD
X#include "shadow.h"
Xstruct spwd *spwd;
Xstruct spwd *getspnam();
X#endif
Xstruct group *grp;
Xstruct group *getgrgid();
Xstruct group *getgrnam();
X
Xchar *getlogin();
Xchar *crypt();
Xvoid shell();
X
Xchar *name;
Xchar *group;
Xint gid;
X
Xchar *Prog;
Xchar prog[BUFSIZ];
Xchar base[BUFSIZ];
Xchar passwd[BUFSIZ];
Xchar *cpasswd;
Xchar *salt;
X
X#ifndef MAXENV
X#define MAXENV 64
X#endif
X
Xchar *newenvp[MAXENV];
Xint newenvc = 0;
Xint maxenv = MAXENV;
X
X/*
X * usage - print command usage message
X */
X
Xusage ()
X{
X fprintf (stderr, "usage: newgrp [ - ] [ group ]\n");
X exit (1);
X}
X
X/*
X * newgrp - change the invokers current real and effective group id
X */
X
Xmain (argc, argv, envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
X int initflag = 0;
X int needspasswd = 0;
X int i;
X char *cp;
X#ifdef DOUBLESIZE
X int longpass;
X#endif
X
X /*
X * let me parse the command line first. the only legal flag
X * is a "-", which indicates the shell is to perform the same
X * initialization it does at login time. the remaining
X * optional argument is the name of a new group. if it isn't
X * present i just use the login group id of this user.
X */
X
X if (argc > 1 && strcmp (argv[1], "-") == 0) {
X initflag = 1;
X argc--; argv++;
X }
X if (argc > 2)
X usage ();
X
X#ifdef NGROUPS
X
X /*
X * get the current users groupset. the new group will be
X * added to the concurrent groupset if there is room, otherwise
X * you get a nasty message but at least your real and effective
X * group id's are set.
X */
X
X ngroups = getgroups (groups);
X#endif
X
X /*
X * save my name for error messages and save my real gid incase
X * of errors. if there is an error i have to exec a new login
X * shell for the user since her old shell won't have fork'd to
X * create the process.
X */
X
X Prog = argv[0];
X gid = getgid ();
X
X /*
X * now i get to determine my current name. i do this to validate
X * my access to the requested group. the validation works like
X * this -
X * 1) get the name associated with my current user id
X * 2) get my login name, as told by getlogin().
X * 3) if they match, my name is the login name
X * 4) if they don't match, my name is the name in the
X * password file.
X *
X * this isn't perfect, but it works more often then not.
X */
X
X pwd = getpwuid (getuid ());
X
X if (! (name = getlogin ()) || strcmp (name, pwd->pw_name) != 0)
X name = pwd->pw_name;
X
X if (! (pwd = getpwnam (name))) {
X fprintf (stderr, "unknown user: %s\n", name);
X exit (1);
X }
X
X /*
X * now we determine the name of the new group which she wishes
X * to become a member of. the password file entry for her
X * current user id has been gotten. if there is no optional
X * group argument she will have her real and effective group id
X * set to the value from her password file entry. otherwise
X * we validate her access to the specified group.
X */
X
X if (argv[1] != (char *) 0) {
X
X /*
X * start by getting the entry for the requested group.
X */
X
X if (! (grp = getgrnam (group = argv[1]))) {
X fprintf (stderr, "unknown group: %s\n", group);
X goto failure;
X }
X
X /*
X * see if she is a member of this group.
X */
X
X for (i = 0;grp->gr_mem[i];i++)
X if (strcmp (name, grp->gr_mem[i]) == 0)
X break;
X
X /*
X * if she isn't a member, she needs to provide the
X * group password. if there is no group password, she
X * will be denied access anyway.
X */
X
X if (grp->gr_mem[i] == (char *) 0)
X needspasswd = 1;
X#ifdef SHADOWPWD
X
X /*
X * if she does not have either a shadowed password,
X * or a regular password, and the group has a password,
X * she needs to give the group password.
X */
X
X if (spwd = getspnam (name)) {
X if (spwd->sp_pwdp[0] == '\0' && grp->gr_passwd[0])
X needspasswd = 1;
X } else {
X if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0])
X needspasswd = 1;
X }
X#else
X
X /*
X * if she does not have a regular password she will have
X * to give the group password, if one exists.
X */
X
X if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0])
X needspasswd = 1;
X#endif
X } else {
X
X /*
X * get the group file entry for her login group id.
X * the entry must exist, simply to be annoying.
X */
X
X if (! (grp = getgrgid (pwd->pw_gid))) {
X fprintf (stderr, "unknown gid: %d\n", pwd->pw_gid);
X goto failure;
X }
X }
X
X /*
X * now i see about letting her into the group she requested.
X * if she is the root user, i'll let her in without having to
X * prompt for the password. otherwise i ask for a password
X * if she flunked one of the tests above. note that she
X * won't have to provide the password to her login group even
X * if she isn't listed as a member.
X */
X
X if (getuid () != 0 && needspasswd) {
X passwd[0] = '\0';
X
X if (grp->gr_passwd[0]) {
X
X /*
X * get the password from her, and set the salt for
X * the decryption from the group file.
X */
X
X if (! (cp = getpass ("Password:")))
X goto failure;
X
X strcpy (passwd, cp);
X salt = grp->gr_passwd;
X } else {
X
X /*
X * there is no password, print out "Sorry" and give up
X */
X
X fputs ("Sorry\n", stderr);
X goto failure;
X }
X
X /*
X * encrypt the key she gave us using the salt from
X * the password in the group file. the result of
X * this encryption must match the previously
X * encrypted value in the file.
X */
X
X cpasswd = pw_encrypt (passwd, salt);
X
X if (strcmp (cpasswd, grp->gr_passwd) != 0) {
X fputs ("Sorry\n", stderr);
X goto failure;
X }
X }
X
X /*
X * all successful validations pass through this point. the
X * group id will be set, and the group added to the concurrent
X * groupset.
X */
X
X gid = grp->gr_gid;
X#ifdef NGROUPS
X
X /*
X * i am going to try to add her new group id to her concurrent
X * group set. if the group id is already present i'll just
X * skip this part. if the group doesn't fit, i'll complain
X * loudly and skip this part ...
X */
X
X for (i = 0;i < ngroups;i++) {
X if (gid == groups[i])
X break;
X }
X if (i == ngroups) {
X if (ngroups == NGROUPS) {
X fprintf (stderr, "too many groups\n");
X } else {
X groups[ngroups++] = gid;
X if (setgroups (ngroups, groups)) {
X fprintf (stderr, "%s: ", Prog);
X perror ("unable to set groups");
X }
X }
X }
X#endif
X
X /*
X * this is where all failures land. the group id will not
X * have been set, so the setgid() below will set me to the
X * original group id i had when i was invoked.
X */
X
Xfailure:
X
X /*
X * i set her group id either to the value she requested, or
X * to the original value. i have to go back to the original
X * because she no longer has a shell running.
X */
X
X if (setgid (gid))
X perror ("setgid");
X
X if (setuid (getuid ()))
X perror ("setuid");
X
X /*
X * i have to get the pathname of her login shell. as a favor
X * i'll try her environment for a $SHELL value first, and
X * then try the password file entry.
X */
X
X if (! initflag && (cp = getenv ("SHELL")))
X strncpy (prog, cp, sizeof prog);
X else if (pwd->pw_shell && pwd->pw_shell[0])
X strncpy (prog, pwd->pw_shell, sizeof prog);
X else
X strcpy (prog, "/bin/sh");
X
X /*
X * now i try to find the basename of the login shell. this
X * will become argv[0] of the spawned command.
X */
X
X if (cp = strrchr (prog, '/'))
X cp++;
X else
X cp = prog;
X
X /*
X * to have the shell perform login processing i will set the
X * first character in the first argument to a "-".
X */
X
X if (initflag)
X strcat (strcpy (base, "-"), cp);
X else
X strcpy (base, cp);
X
X#ifdef SHADOWPWD
X endspent ();
X#endif
X endpwent ();
X endgrent ();
X
X /*
X * switch back to her home directory if i am doing login
X * initialization.
X */
X
X if (initflag) {
X chdir (pwd->pw_dir);
X while (*envp) {
X if (strncmp (*envp, "PATH=", 5) == 0 ||
X strncmp (*envp, "HOME=", 5) == 0 ||
X strncmp (*envp, "SHELL=", 6) == 0)
X addenv (*envp);
X
X envp++;
X }
X } else {
X while (*envp)
X addenv (*envp++);
X }
X
X /*
X * exec the login shell and go away.
X */
X
X shell (prog, base);
X /*NOTREACHED*/
X}
SHAR_EOF
if test 8576 -ne "`wc -c < 'newgrp.c'`"
then
echo shar: "error transmitting 'newgrp.c'" '(should have been 8576 characters)'
fi
fi
echo shar: "extracting 'Makefile'" '(11315 characters)'
if test -f 'Makefile'
then
echo shar: "will not over-write existing file 'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X#
X# Copyright 1988,1989,1990, John F. Haugh II
X# All rights reserved.
X#
X# Permission is granted to copy and create derivative works for any
X# non-commercial purpose, provided this copyright notice is preserved
X# in all copies of source code, or included in human readable form
X# and conspicuously displayed on all copies of object code or
X# distribution media.
X#
X# %W% %U% - Shadow password system
X#
X# %W% %U% %G%
X#
XSHELL = /bin/sh
X
X#
X# Set this flag to decide what level of code "get" returns.
X# The base USENET release was release 1. It is no longer supported.
X# The version with the utilities added was release 2.
X# The unreleased version with database-like file access is release 3.
XRELEASE = 3
XGFLAGS = -t -r$(RELEASE)
X
X# Define the directory login is copied to. BE VERY CAREFUL!!!
X# LOGINDIR = /bin
XLOGINDIR = /etc
X
X# Pick your favorite C compiler and tags command
XCC = cc
XTAGS = ctags
X
X# OS. Currently only BSD and USG are defined. If you don't use BSD,
X# USG (System V) is assumed.
XOS = -DUSG
X# OS = -DBSD
X
X# Do you have to do ranlib? Sorry to hear that ...
XRANLIB = ranlib
X# RANLIB = echo
X
X# Flags for SCO Xenix/386
XCFLAGS = -O -M3 -g $(OS)
XLIBS = -lcrypt -lndbm
X# LIBS = -lcrypt -ldbm
XLDFLAGS = -M3 -g
XLTFLAGS =
X# This should be Slibsec.a for small model, or Llibsec.a for
X# large model or whatever. MUST AGREE WITH CFLAGS!!!
XLIBSEC = Slibsec.a
X
X# Flags for normal machines
X# CFLAGS = -O -g $(OS)
X# LIBS =
X# LDFLAGS = -g
X# LIBSEC = libsec.a
X
X# Names for root user and group, and bin user and group
XRUID = root
XRGID = root
XBUID = bin
XBGID = bin
X
X# Rules for .L (lint) files.
X.SUFFIXES: .L
XLINT = lint
XLINTFLAGS = $(OS) -Dlint
X
X.c.L:
X $(LINT) -u $(LINTFLAGS) $*.c > $*.L
X
XLOBJS = lmain.o login.o env.o valid.o setup.o shell.o age.o \
X utmp.o sub.o mail.o motd.o log.o ttytype.o failure.o
X
XLSRCS = lmain.c login.c env.c valid.c setup.c shell.c age.c \
X utmp.c sub.c mail.c motd.c log.c ttytype.c failure.c
X
XSOBJS = smain.o env.o entry.o susetup.o shell.o \
X sub.o mail.o motd.o sulog.o age.o
X
XSSRCS = smain.c env.c entry.c setup.c shell.c \
X pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c
X
XPOBJS = passwd.o obscure.o
XPSRCS = passwd.c obscure.c
X
XGPSRCS = gpmain.c
X
XGPOBJS = gpmain.o
X
XPWOBJS = pwconv.o
X
XPWSRCS = pwconv.c pwent.c shadow.c pwpack.c rad64.c
X
XPWUNOBJS = pwunconv.o
X
XPWUNSRCS = pwunconv.c pwent.c shadow.c pwpack.c rad64.c
X
XSULOGOBJS = sulogin.o entry.o env.o age.o setup.o \
X valid.o shell.o
X
XSULOGSRCS = sulogin.c entry.c env.c age.c pwent.c setup.c \
X shadow.c shell.c valid.c pwpack.c
X
XMKPWDOBJS = mkpasswd.o
X
XMKPWDSRCS = mkpasswd.c
X
XNGSRCS = newgrp.c env.c shell.c
X
XNGOBJS = newgrp.o env.o shell.o
X
XCHFNSRCS = chfn.c fields.c
XCHFNOBJS = chfn.o fields.o
XCHSHSRCS = chsh.c fields.c
XCHSHOBJS = chsh.o fields.o
XCHAGEOBJS = chage.o fields.o
XCHAGESRCS = chage.c fields.c
XCHPASSOBJS = chpasswd.o
XCHPASSSRCS = chpasswd.c
XDPSRCS = dpmain.c
XDPOBJS = dpmain.o
X
XALLSRCS = age.c dialchk.c dialup.c entry.c env.c lmain.c log.c login.c mail.c \
X motd.c obscure.c passwd.c pwconv.c pwent.c pwunconv.c getpass.c \
X setup.c shadow.c shell.c smain.c sub.c sulog.c sulogin.c ttytype.c \
X utmp.c valid.c port.c newgrp.c gpmain.c grent.c mkpasswd.c pwpack.c \
X chfn.c chsh.c chage.c rad64.c encrypt.c chpasswd.c shadowio.c pwio.c \
X newusers.c groupio.c fields.c pwdbm.c grpack.c grdbm.c sppack.c \
X spdbm.c dpmain.c gshadow.c gsdbm.c gspack.c sgroupio.c
X
XFILES1 = README newgrp.c Makefile config.h pwunconv.c obscure.c age.c
X
XFILES2 = passwd.c port.c lmain.c mkpasswd.c sulogin.c pwpack.c dialup.c \
X sulog.c getpass.c
X
XFILES3 = chfn.c chsh.c smain.c faillog.c pwconv.c failure.c utmp.c shadow.c
X
XFILES4 = gpmain.c chage.c pwent.c valid.c setup.c entry.c ttytype.c port.h
X
XFILES5 = pwio.c encrypt.c chpasswd.c newusers.c rad64.c dialchk.c faillog.h \
X pwdbm.c grdbm.c gshadow.c sppack.c
X
XFILES6 = gspack.c spdbm.c lastlog.h shell.c login.c sub.c dpmain.c mail.c \
X env.c pwd.h grpack.c shadow.h log.c grent.c motd.c dialup.h fields.c \
X gsdbm.c
X
XFILES7 = groupio.c shadowio.c sgroupio.c
X
XMAN_1 = chage.1 chfn.1 chsh.1 login.1 passwd.1 su.1
XMAN_3 = shadow.3
XMAN_4 = faillog.4 passwd.4 porttime.4 shadow.4
XMAN_8 = faillog.8 pwconv.8 pwunconv.8 sulogin.8
X
XDOCS = $(MAN_1) $(MAN_3) $(MAN_4) $(MAN_8)
X
XBINS = su login pwconv pwunconv passwd sulogin faillog newgrp gpasswd \
X mkpasswd chfn chsh chage chpasswd newusers dpasswd id
X
Xall: $(BINS) $(DOCS)
X
X.PRECIOUS: libshadow.a
Xlibshadow.a: \
X libshadow.a(dialchk.o) \
X libshadow.a(dialup.o) \
X libshadow.a(encrypt.o) \
X libshadow.a(getpass.o) \
X libshadow.a(grdbm.o) \
X libshadow.a(grent.o) \
X libshadow.a(groupio.o) \
X libshadow.a(grpack.o) \
X libshadow.a(gshadow.o) \
X libshadow.a(gsdbm.o) \
X libshadow.a(gspack.o) \
X libshadow.a(sgroupio.o) \
X libshadow.a(port.o) \
X libshadow.a(pwdbm.o) \
X libshadow.a(pwent.o) \
X libshadow.a(pwio.o) \
X libshadow.a(pwpack.o) \
X libshadow.a(rad64.o) \
X libshadow.a(spdbm.o) \
X libshadow.a(shadow.o) \
X libshadow.a(shadowio.o) \
X libshadow.a(sppack.o)
X $(RANLIB) libshadow.a
X
Xlibsec: $(LIBSEC)(shadow.o)
X $(RANLIB) $(LIBSEC)
X
Xinstall: all
X strip $(BINS)
X cp login $(LOGINDIR)/login
X cp mkpasswd pwconv pwunconv sulogin chpasswd newusers /etc
X cp su passwd gpasswd dpasswd faillog newgrp chfn chsh id /bin
X cp dialup.h shadow.h pwd.h /usr/include
X chown $(RUID) $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
X /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd \
X /bin/dpasswd /bin/chsh /bin/chfn /bin/chage
X chgrp $(RGID) $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
X /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd \
X /bin/dpasswd /bin/chsh /bin/chfn /bin/chage
X chown $(BUID) /bin/faillog /bin/id /usr/include/shadow.h \
X /usr/include/dialup.h /usr/include/pwd.h
X chgrp $(BGID) /bin/faillog /bin/id /usr/include/shadow.h \
X /usr/include/dialup.h /usr/include/pwd.h
X chmod 700 /etc/pwconv /etc/pwunconv /etc/sulogin /etc/mkpasswd \
X /etc/chpasswd /etc/newusers /bin/dpasswd /bin/chage
X chmod 4711 $(LOGINDIR)/login /bin/su /bin/passwd /bin/gpasswd \
X /bin/newgrp /bin/chfn /bin/chsh
X chmod 711 /bin/faillog /bin/id
X chmod 444 /usr/include/shadow.h /usr/include/dialup.h \
X /usr/include/pwd.h
X
Xlint: su.lint login.lint pwconv.lint pwunconv.lint passwd.lint sulogin.lint \
X faillog.lint newgrp.lint gpasswd.lint mkpasswd.lint chfn.lint \
X chsh.lint chage.lint dpasswd.lint $(ALLSRCS:.c=.L)
X
Xtags: $(ALLSRCS)
X $(TAGS) $(ALLSRCS)
X
XREADME: s.README
X get -t -r$(RELEASE) s.README
X
X$(DOCS):
X get -t -r$(RELEASE) s.$@
X
Xlogin: $(LOBJS) libshadow.a
X $(CC) -o login $(LDFLAGS) $(LOBJS) libshadow.a $(LIBS)
X
Xlogin.lint: $(LSRCS)
X $(LINT) $(LINTFLAGS) $(LSRCS) > login.lint
X
Xsu: $(SOBJS) libshadow.a
X $(CC) -o su $(LDFLAGS) $(SOBJS) libshadow.a $(LIBS)
X
Xsu.lint: $(SSRCS)
X $(LINT) $(LINTFLAGS) -DSU $(SSRCS) > su.lint
X
Xpasswd: $(POBJS) libshadow.a
X $(CC) -o passwd $(LDFLAGS) $(POBJS) libshadow.a $(LIBS)
X
Xpasswd.lint: $(PSRCS)
X $(LINT) $(LINTFLAGS) -DPASSWD $(PSRCS) > passwd.lint
X
Xgpasswd: $(GPOBJS) libshadow.a
X $(CC) -o gpasswd $(LDFLAGS) $(GPOBJS) libshadow.a $(LIBS)
X
Xgpasswd.lint: $(GPSRCS)
X $(LINT) $(LINTFLAGS) $(GPSRCS) > gpasswd.lint
X
Xdpasswd: $(DPOBJS) libshadow.a
X $(CC) -o dpasswd $(LDFLAGS) $(DPOBJS) libshadow.a $(LIBS)
X
Xdpasswd.lint: $(DPSRCS)
X $(LINT) $(LINTFLAGS) $(DPSRCS) > dpasswd.lint
X
Xpwconv: $(PWOBJS) libshadow.a config.h
X $(CC) -o pwconv $(LDFLAGS) $(PWOBJS) libshadow.a $(LIBS)
X
Xpwconv.lint: $(PWSRCS) config.h
X $(LINT) $(LINTFLAGS) -DPASSWD $(PWSRCS) > pwconv.lint
X
Xpwunconv: $(PWUNOBJS) libshadow.a config.h
X $(CC) -o pwunconv $(LDFLAGS) $(PWUNOBJS) libshadow.a $(LIBS)
X
Xpwunconv.lint: $(PWUNSRCS)
X $(LINT) $(LINTFLAGS) -DPASSWD $(PWUNSRCS) > pwunconv.lint
X
Xsulogin: $(SULOGOBJS) libshadow.a
X $(CC) -o sulogin $(LDFLAGS) $(SULOGOBJS) libshadow.a $(LIBS)
X
Xsulogin.lint: $(SULOGSRCS)
X $(LINT) $(LINTFLAGS) $(SULOGSRCS) > sulogin.lint
X
Xfaillog: faillog.o
X $(CC) -o faillog $(LDFLAGS) faillog.o $(LIBS)
X
Xfaillog.lint: faillog.c faillog.h config.h
X $(LINT) $(LINTFLAGS) faillog.c > faillog.lint
X
Xmkpasswd: $(MKPWDOBJS) libshadow.a
X $(CC) -o mkpasswd $(LDFLAGS) $(MKPWDOBJS) libshadow.a $(LIBS)
X
Xmkpasswd.lint: $(MKPWDSRCS)
X $(LINT) $(LINTFLAGS) $(MKPWDSRCS) > mkpasswd.lint
X
Xnewgrp: $(NGOBJS) libshadow.a
X $(CC) -o newgrp $(LDFLAGS) $(NGOBJS) libshadow.a $(LIBS)
X
Xnewgrp.lint: $(NGSRCS)
X $(LINT) $(LINTFLAGS) $(NGSRCS) > newgrp.lint
X
Xchfn: $(CHFNOBJS) libshadow.a
X $(CC) -o chfn $(LDFLAGS) $(CHFNOBJS) libshadow.a $(LIBS)
X
Xchfn.lint: $(CHFNSRCS)
X $(LINT) $(LINTFLAGS) $(CHFNSRCS) > chfn.lint
X
Xchsh: $(CHSHOBJS) libshadow.a
X $(CC) -o chsh $(LDFLAGS) $(CHSHOBJS) libshadow.a $(LIBS)
X
Xchsh.lint: $(CHSHSRCS)
X $(LINT) $(LINTFLAGS) $(CHSHSRCS) > chsh.lint
X
Xchage: $(CHAGEOBJS) libshadow.a
X $(CC) -o chage $(LDFLAGS) $(CHAGEOBJS) libshadow.a $(LIBS)
X
Xchage.lint: $(CHAGESRCS)
X $(LINT) $(LINTFLAGS) -DPASSWD $(CHAGESRCS) > chage.lint
X
Xchpasswd: $(CHPASSOBJS) libshadow.a
X $(CC) -o chpasswd $(LDFLAGS) $(CHPASSOBJS) libshadow.a $(LIBS)
X
Xchpasswd.lint: $(CHPASSSRCS)
X $(LINT) $(LINTFLAGS) $(CHPASSSRCS) > chpasswd.lint
X
Xnewusers: newusers.o libshadow.a
X $(CC) -o newusers $(LDFLAGS) newusers.o libshadow.a $(LIBS)
X
Xnewusers.lint: newusers.c
X $(LINT) $(LINTFLAGS) newusers.c > newusers.lint
X
Xid: id.o libshadow.a
X $(CC) -o id $(LDFLAGS) id.o libshadow.a $(LIBS)
X
Xid.lint: id.c
X $(LINT) $(LINTFLAGS) id.c > id.lint
X
Xsulog.o: config.h
X
Xsusetup.c: setup.c
X cp setup.c susetup.c
X
Xsusetup.o: config.h setup.c pwd.h
X $(CC) -c $(CFLAGS) -DSU susetup.c
X
Xpasswd.o: config.h shadow.h pwd.h
Xlmain.o: config.h lastlog.h faillog.h pwd.h
Xsmain.o: config.h lastlog.h pwd.h shadow.h
Xsub.o: pwd.h
Xsetup.o: config.h pwd.h
X
Xutmp.o: config.h
X
Xmail.o: config.h
X
Xmotd.o: config.h
X
Xage.o: config.h pwd.h
X
Xlog.o: config.h lastlog.h pwd.h
X
Xshell.o: config.h
X
Xentry.o: config.h shadow.h pwd.h
X
Xshadow.o: shadow.h config.h
Xshadowio.o: shadow.h
Xgrent.o: config.h shadow.h
Xsgroupio.o: shadow.h
Xdialup.o: dialup.h
Xdialchk.o: dialup.h config.h
Xpwdbm.o: config.h pwd.h
Xpwpack.o: config.h pwd.h
Xpwent.o: config.h pwd.h
Xpwio.o: pwd.h
Xgetpass.o: config.h
Xencrypt.o: config.h
Xport.o: port.h
X
Xvalid.o: config.h pwd.h
X
Xfailure.o: faillog.h config.h
X
Xfaillog.o: faillog.h config.h pwd.h
X
Xnewgrp.o: config.h shadow.h pwd.h
X
Xmkpasswd.o: config.h shadow.h pwd.h
X
Xgpmain.o: config.h pwd.h
X
Xchfn.o: config.h pwd.h
X
Xchsh.o: config.h pwd.h
X
Xchage.o: config.h shadow.h pwd.h
X
Xpwconv.o: config.h shadow.h
X
Xpwunconv.o: config.h shadow.h pwd.h
X
Xchpasswd.o: config.h shadow.h pwd.h
Xid.o: pwd.h
Xnewusers.o: config.h shadow.h pwd.h
Xdpmain.o: dialup.h
X
Xclean:
X -rm -f *.o a.out core npasswd nshadow *.pag *.dir
X
Xclobber: clean
X -rm -f $(BINS) *.lint *.L susetup.c libshadow.a
X
Xnuke: clobber
X -for file in * ; do \
X if [ -f s.$$file -a ! -f p.$$file ] ; then \
X rm -f $$file ;\
X fi ;\
X done
X
Xshar: login.sh.1 login.sh.2 login.sh.3 login.sh.4 login.sh.5 login.sh.6 \
X login.sh.7 login.sh.8
X
Xlogin.sh.1: $(FILES1) Makefile
X shar -a $(FILES1) > login.sh.1
X
Xlogin.sh.2: $(FILES2) Makefile
X shar -a $(FILES2) > login.sh.2
X
Xlogin.sh.3: $(FILES3) Makefile
X shar -a $(FILES3) > login.sh.3
X
Xlogin.sh.4: $(FILES4) Makefile
X shar -a $(FILES4) > login.sh.4
X
Xlogin.sh.5: $(FILES5) Makefile
X shar -a $(FILES5) > login.sh.5
X
Xlogin.sh.6: $(FILES6) Makefile
X shar -a $(FILES6) > login.sh.6
X
Xlogin.sh.7: $(FILES7) Makefile
X shar -a $(FILES7) > login.sh.7
X
Xlogin.sh.8: $(DOCS) Makefile
X shar -a $(DOCS) > login.sh.8
SHAR_EOF
if test 11315 -ne "`wc -c < 'Makefile'`"
then
echo shar: "error transmitting 'Makefile'" '(should have been 11315 characters)'
fi
fi
echo shar: "extracting 'config.h'" '(6820 characters)'
if test -f 'config.h'
then
echo shar: "will not over-write existing file 'config.h'"
else
sed 's/^X//' << \SHAR_EOF > 'config.h'
X/*
X * Copyright 1989, 1990, John F. Haugh II
X * All rights reserved.
X *
X * Use, duplication, and disclosure prohibited without
X * the express written permission of the author.
X */
X
X/*
X * Configuration file for login.
X *
X * @(#)config.h 3.4 14:43:20 12/18/90
X */
X
X/*
X * Define DIALUP to use dialup password files. Define PORTTIME
X * to use the port time restriction file, see port.h for more
X * information.
X */
X
X#define DIALUP
X#define PORTTIME
X
X/*
X * Define SHADOWPWD to use shadow [ unreadable ] password file.
X * Release 3 has a requirement that SHADOWPWD always be defined.
X * Define AUTOSHADOW to have root always copy sp_pwdp to pw_passwd
X * for getpwuid() and getpwnam(). This provides compatibility for
X * privileged applications which are shadow-ignorant. YOU ARE
X * ENCOURAGED TO NOT USE THIS OPTION UNLESS ABSOLUTELY NECESSARY.
X */
X
X#define SHADOWPWD
X#undef AUTOSHADOW
X
X/*
X * Define DOUBLESIZE to use 16 character passwords
X */
X
X#define DOUBLESIZE
X
X/*
X * Define OBSCURE to include hard password testing code.
X */
X
X#define OBSCURE
X
X/*
X * Define PASSLENGTH to be shortest legal password
X */
X
X#define PASSLENGTH 5
X
X/*
X * Define NOBLANK if you want all passwords prompted for, including
X * empty ones.
X
X#undef NOBLANK
X
X/*
X * Define MAXDAYS to be the default maximum number of days a password
X * is valid for when converting to shadow passwords. Define MINDAYS
X * to be the minimum number of days before a password may be changed.
X * See pwconv.c for more details.
X */
X
X#define MAXDAYS 10000
X#define MINDAYS 0
X
X/*
X * Define NDEBUG for production versions
X */
X
X#define NDEBUG
X
X/*
X * Define HZ if login must set HZ value
X */
X
X#define HZ "HZ=50"
X
X/*
X * Define TZ if login must set timezone
X *
X * The first example sets the variable directly. The
X * second example names a file which is read to determine
X * the proper value. The file consists of a single line
X * of the form 'TZ=zone-name'
X */
X
X/* #define TZ "TZ=CST6CDT" */
X#define TZ "/etc/tzname"
X
X/*
X * Define the default PATH and SUPATH here. PATH is for non-privileged
X * users, SUPATH is for root. The first pair are for real trusting
X * systems, the second pair are for the paranoid ...
X */
X
X/* #define PATH "PATH=:/bin:/usr/bin" */
X/* #define SUPATH "PATH=:/bin:/usr/bin:/etc" */
X#define PATH "PATH=/bin:/usr/bin"
X#define SUPATH "PATH=/bin:/usr/bin:/etc"
X
X/*
X * Define the mailbox directory
X */
X
X#define MAILDIR "/usr/spool/mail/"
X
X/*
X * Define AGING if you want the password aging checks made.
X * Define WARNAGE to be the number of days notice a user receives
X * of a soon to expire password. Release 3 has a requirement that
X * AGING always be defined.
X */
X
X#define AGING
X#define WARNAGE 10
X
X/*
X * Define MAILCHECK if you want the mailbox checked for new mail
X *
X * One of two messages are printed - `You have new mail.' or
X * `You have mail.'.
X */
X
X#define MAILCHECK
X
X/*
X * Define CONSOLE if you want ROOT restricted to a particular terminal.
X *
X * Use the name of the tty line if you only want a single line, or use
X * the name of the file containing the permissible ports if you wish to
X * allow root logins on more than one port.
X */
X
X/* #define CONSOLE "console" /* root on /dev/console only */
X#define CONSOLE "/etc/consoles" /* check /etc/consoles for a list */
X
X/*
X * Define NOLOGINS if you want to be able to deny non-root users logins.
X * Logins will not be permitted if this file exists.
X */
X
X#define NOLOGINS "/etc/nologin"
X
X/*
X * Define NOUSE if you want to be able to declare accounts which can't
X * be logged into. Define NOLOGIN if you want it to be an su-only account.
X */
X
X#define NOUSE "NOUSE"
X#define NOLOGIN "NOLOGIN"
X
X/*
X * Define MOTD if you want the message of the day (/etc/motd) printed
X * at login time.
X */
X
X#define MOTD
X
X/*
X * Define HUSHLOGIN if you want the code added to avoid printing the
X * motd if a file $HOME/.hushlogin exists. This obviously only matters
X * if any of MOTD, MAILCHECK or LASTLOG are #define'd.
X */
X
X#define HUSHLOGIN
X
X/*
X * Define LASTLOG if you want a record made of logins in /usr/adm/lastlog.
X */
X
X#define LASTLOG
X
X/*
X * Define FAILLOG if you want a record make of failed logins in
X * /usr/adm/faillog. See faillog.h for more details. See fail(1L)
X * for even still more details ... Also, define FTMP to record utmp
X * style records for failed logins. FTMP is the name of a utmp-like
X * file. You can use who(1) instead of faillog(L), which is an
X * advantage. Define UNKNOWNS if you do want unknown user names
X * recorded. This can be a security hole since passwords are often
X * entered mistakenly as user names.
X */
X
X#define FAILLOG
X#define FTMP "/etc/ftmp"
X#define UNKNOWNS
X
X/*
X * Define TTYPERM to be the initial terminal permissions. Defining
X * as 0600 will not allow messages, 0622 will.
X */
X
X#define TTYPERM 0600
X
X/*
X * Define TTYTYPE to the be name of the port to terminal type
X * mapping file. This is used to set the environmental variable
X * "TERM" to the correct terminal type.
X */
X
X#define TTYTYPE "/etc/ttytype"
X
X/*
X * Define QUOTAS if you want the code added in setup.c to support
X * file ulimit and nice [ and umask as well ] setting from the password
X * file.
X */
X
X#define QUOTAS
X
X/*
X * Pick your version of DBM. If you define either DBM or NDBM, you
X * must define GETPWENT. If you define NDBM you must define GETGRENT
X * as well.
X */
X
X/* #define DBM /* */
X#define NDBM /* */
X
X/*
X * Define file name for sulog. If SULOG is not defined, there will be
X * no logging. This is NOT a good idea ... We also define other file
X * names.
X */
X
X#define SULOG "/usr/adm/sulog"
X#define SUCON "/dev/console"
X#define PWDFILE "/etc/passwd"
X#define OPWDFILE "/etc/passwd-"
X#define NPWDFILE "/etc/npasswd"
X#define OSHADOW "/etc/shadow-"
X#define NSHADOW "/etc/nshadow"
X#define GRPFILE "/etc/group"
X#define OGRPFILE "/etc/group-"
X#define NGRPFILE "/etc/ngroup"
X
X/*
X * Define PWDLOCK to be a locking semaphore for updating the password
X * file. GRPLOCK is the same for the group file.
X */
X
X#define PWDLOCK "/etc/passwd.lock"
X#define GRPLOCK "/etc/group.lock"
X#define SPWLOCK "/etc/shadow.lock"
X
X/*
X * Wierd stuff follows ...
X *
X * The following macros exist solely to override stuff ...
X * You will probably want to change their values to suit your
X * fancy.
X */
X
X#define ERASECHAR '\b'
X#define KILLCHAR '\025'
X#define UMASK 022
X
X#define ULIMIT (1L<<20) /* Define if your UNIX supports ulimit() */
X#define FGETPWENT /* Define if library does not include FGETPWENT */
X#define GETPWENT /* Define if you want my GETPWENT(3) routines */
X#define GETGRENT /* Define if you want my GETGRENT(3) routines */
X#define NEED_AL64 /* Define if library does not include a64l() */
X
X/*
X * These macros control the contents of <pwd.h>.
X */
X
X#define ATT_AGE /* the pw_age field exists */
X#define ATT_COMMENT /* the pw_comment field exists */
X#undef BSD_QUOTA /* the pw_quota field exists */
SHAR_EOF
if test 6820 -ne "`wc -c < 'config.h'`"
then
echo shar: "error transmitting 'config.h'" '(should have been 6820 characters)'
fi
fi
echo shar: "extracting 'pwunconv.c'" '(3162 characters)'
if test -f 'pwunconv.c'
then
echo shar: "will not over-write existing file 'pwunconv.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pwunconv.c'
X/*
X * Copyright 1989, 1990, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X *
X * pwunconv - restore old password file from shadow password file.
X *
X * Pwunconv copies the password file information from the shadow
X * password file, merging entries from an optional existing shadow
X * file.
X *
X * The new password file is left in npasswd. There is no new
X * shadow file. Password aging information is translated where
X * possible.
X */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <fcntl.h>
X#include "pwd.h"
X#include "config.h"
X#include "shadow.h"
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)pwunconv.c 3.2 12:31:26 12/12/90";
X#endif
X
X#ifdef ITI_AGING
X#define WEEK (7L*24L*3600L)
X#else
X#define WEEK (7)
X#endif
X
Xchar buf[BUFSIZ];
Xchar *l64a ();
X
Xint main ()
X{
X struct passwd *pw;
X struct passwd *sgetpwent ();
X FILE *pwd;
X FILE *npwd;
X struct spwd *spwd;
X int fd;
X char newage[5];
X
X if (! (pwd = fopen (PWDFILE, "r"))) {
X perror (PWDFILE);
X return (1);
X }
X unlink ("npasswd");
X if ((fd = open ("npasswd", O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0 ||
X ! (npwd = fdopen (fd, "w"))) {
X perror ("npasswd");
X return (1);
X }
X while (fgets (buf, BUFSIZ, pwd) == buf) {
X buf[strlen (buf) - 1] = '\0'; /* remove '\n' character */
X
X if (buf[0] == '#') { /* comment line */
X (void) fprintf (npwd, "%s\n", buf);
X continue;
X }
X if (! (pw = sgetpwent (buf))) { /* copy bad lines verbatim */
X (void) fprintf (npwd, "%s\n", buf);
X continue;
X }
X setspent (); /* rewind shadow file */
X
X if (! (spwd = getspnam (pw->pw_name))) {
X (void) fprintf (npwd, "%s\n", buf);
X continue;
X }
X pw->pw_passwd = spwd->sp_pwdp;
X
X /*
X * Password aging works differently in the two different systems.
X * With shadow password files you apparently must have some aging
X * information. The maxweeks or minweeks may not map exactly.
X * In pwconv we set max == 10000, which is about 30 years. Here
X * we have to undo that kludge. So, if maxdays == 10000, no aging
X * information is put into the new file. Otherwise, the days are
X * converted to weeks and so on.
X */
X
X#ifdef ATT_AGE
X if (spwd->sp_max > (63*WEEK) && spwd->sp_max < 10000)
X spwd->sp_max = (63*WEEK); /* 10000 is infinity */
X
X if (spwd->sp_min >= 0 && spwd->sp_min <= 63*7 &&
X spwd->sp_max >= 0 && spwd->sp_max <= 63*7) {
X if (spwd->sp_lstchg == -1)
X spwd->sp_lstchg = 0;
X
X spwd->sp_max /= WEEK; /* turn it into weeks */
X spwd->sp_min /= WEEK;
X spwd->sp_lstchg /= WEEK;
X
X strncpy (newage, l64a (spwd->sp_lstchg * (64L*64L) +
X spwd->sp_min * (64L) + spwd->sp_max), 5);
X pw->pw_age = newage;
X } else
X pw->pw_age = "";
X#endif /* ATT_AGE */
X if (putpwent (pw, npwd)) {
X perror (stderr, "pwunconv: write error");
X exit (1);
X }
X }
X endspent ();
X
X if (ferror (npwd)) {
X perror ("pwunconv");
X (void) unlink ("npasswd");
X }
X (void) fclose (npwd);
X (void) fclose (pwd);
X return (0);
X}
SHAR_EOF
if test 3162 -ne "`wc -c < 'pwunconv.c'`"
then
echo shar: "error transmitting 'pwunconv.c'" '(should have been 3162 characters)'
fi
fi
echo shar: "extracting 'obscure.c'" '(3031 characters)'
if test -f 'obscure.c'
then
echo shar: "will not over-write existing file 'obscure.c'"
else
sed 's/^X//' << \SHAR_EOF > 'obscure.c'
X/*
X * Copyright 1989, 1990, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#include <ctype.h>
X#ifndef BSD
X#include <string.h>
X#include <memory.h>
X#else
X#include <strings.h>
X#define strchr index
X#define strrchr rindex
X#endif
X#include "config.h"
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)obscure.c 3.1 11:31:35 12/19/90";
X#endif
X
X/*
X * Obscure - see if password is obscure enough.
X *
X * The programmer is encouraged to add as much complexity to this
X * routine as desired. Included are some of my favorite ways to
X * check passwords.
X */
X
Xint obscure (old, new)
Xchar *old;
Xchar *new;
X{
X#ifdef OBSCURE
X int i;
X char oldmono[32];
X char newmono[32];
X char wrapped[64];
X#endif
X if (old[0] == '\0')
X return (1);
X
X if (strlen (new) < PASSLENGTH) { /* too short */
X printf ("Too short. ");
X return (0);
X }
X#ifdef OBSCURE
X for (i = 0;new[i];i++)
X newmono[i] = tolower (new[i]);
X
X for (i = 0;old[i];i++)
X oldmono[i] = tolower (old[i]);
X
X if (strcmp (new, old) == 0) { /* the same */
X printf ("No Change. ");
X return (0);
X }
X if (palindrome (newmono, oldmono)) /* a palindrome */
X return (0);
X
X if (strcmp (newmono, oldmono) == 0) { /* case shifted */
X printf ("Case changes only. ");
X return (0);
X }
X if (similiar (newmono, oldmono)) /* jumbled version */
X return (0);
X
X if (simple (new, old)) /* keyspace size */
X return (0);
X
X strcpy (wrapped, oldmono);
X strcat (wrapped, oldmono);
X if (strstr (wrapped, newmono)) {
X printf ("Rotated. ");
X return (0);
X }
X#endif
X return (1);
X}
X
X#ifdef OBSCURE
X
X/*
X * can't be a palindrome - like `R A D A R' or `M A D A M'
X */
X
Xint palindrome (old, new)
Xchar *old;
Xchar *new;
X{
X int i, j;
X
X i = strlen (new);
X
X for (j = 0;j < i;j++)
X if (new[i - j - 1] != new[j])
X return (0);
X
X printf ("A palindrome. ");
X return (1);
X}
X
X/*
X * more than half of the characters are different ones.
X */
X
Xint similiar (old, new)
Xchar *old;
Xchar *new;
X{
X int i, j;
X char *strchr ();
X
X for (i = j = 0;new[i] && old[i];i++)
X if (strchr (new, tolower (old[i])))
X j++;
X
X if (i >= j * 2)
X return (0);
X
X printf ("Too similiar. ");
X return (1);
X}
X
X/*
X * a nice mix of characters.
X */
X
Xint simple (old, new)
Xchar *old;
Xchar *new;
X{
X int digits = 0;
X int uppers = 0;
X int lowers = 0;
X int others = 0;
X int size;
X int i;
X double complexity;
X
X for (i = 0;new[i];i++) {
X if (isdigit (new[i]))
X digits++;
X else if (isupper (new[i]))
X uppers++;
X else if (islower (new[i]))
X lowers++;
X else
X others++;
X }
X
X /*
X * The scam is this - a password of only one character type
X * must be 8 letters long. Two types, 7, and so on.
X */
X
X size = 9;
X if (digits) size--;
X if (uppers) size--;
X if (lowers) size--;
X if (others) size--;
X
X if (size <= i)
X return 0;
X
X printf ("Too Simple. ");
X return 1;
X}
X#endif
SHAR_EOF
if test 3031 -ne "`wc -c < 'obscure.c'`"
then
echo shar: "error transmitting 'obscure.c'" '(should have been 3031 characters)'
fi
fi
echo shar: "extracting 'age.c'" '(6179 characters)'
if test -f 'age.c'
then
echo shar: "will not over-write existing file 'age.c'"
else
sed 's/^X//' << \SHAR_EOF > 'age.c'
X/*
X * Copyright 1989, 1990, 1991, John F. Haugh II
X * All rights reserved.
X *
X * Permission is granted to copy and create derivative works for any
X * non-commercial purpose, provided this copyright notice is preserved
X * in all copies of source code, or included in human readable form
X * and conspicuously displayed on all copies of object code or
X * distribution media.
X */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <errno.h>
X#include "config.h"
X#include "pwd.h"
X#include "shadow.h"
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)age.c 3.3 07:52:49 1/30/91";
X#endif
X
X#define DAY (24L*3600L)
X#ifdef ITI_AGING
X#define SCALE (DAY)
X#else
X#define SCALE (1)
X#endif
X
X#ifndef WARNAGE
X#define WARNAGE 10
X#endif
X
Xextern time_t time ();
Xextern char *strdup();
X
X/*
X * pwd_to_spwd - create entries for new spwd structure
X *
X * pwd_to_spwd() creates a new (struct spwd) containing the
X * information in the pointed-to (struct passwd).
X */
X
Xstatic struct spwd *
Xpwd_to_spwd (pw)
Xstruct passwd *pw;
X{
X static struct spwd tspwd;
X struct spwd *sp = &tspwd;
X time_t t;
X
X /*
X * Nice, easy parts first. The name and passwd map directly
X * from the old password structure to the new one.
X */
X
X sp->sp_namp = strdup (pw->pw_name);
X sp->sp_pwdp = strdup (pw->pw_passwd);
X#ifdef ATT_AGE
X
X /*
X * AT&T-style password aging maps the sp_min, sp_max, and
X * sp_lstchg information from the pw_age field, which appears
X * after the encrypted password.
X */
X
X if (pw->pw_age[0]) {
X t = (c64i (pw->pw_age[0]) * 7) * SCALE;
X sp->sp_max = t;
X
X if (pw->pw_age[1]) {
X t = (c64i (pw->pw_age[1]) * 7) * SCALE;
X sp->sp_min = t;
X } else
X sp->sp_min = (10000L) * SCALE;
X
X if (pw->pw_age[1] && pw->pw_age[2]) {
X t = (a64l (pw->pw_age + 2) * 7) * SCALE;
X sp->sp_lstchg = t;
X } else
X sp->sp_lstchg = time ((time_t *) 0) / (DAY/SCALE);
X } else {
X sp->sp_min = 0;
X sp->sp_max = (10000L * SCALE);
X sp->sp_lstchg = time ((time_t *) 0) / (DAY/SCALE);
X }
X#else /* !ATT_AGE */
X /*
X * BSD does not use the pw_age field and has no aging information
X * anywheres. The default values are used to initialize the
X * fields which are in the missing pw_age field;
X */
X
X sp->sp_min = 0;
X sp->sp_max = (10000L * SCALE);
X sp->sp_lstchg = time ((time_t *) 0) / (DAY/SCALE);
X#endif /* ATT_AGE */
X
X /*
X * These fields have no corresponding information in the password
X * file. They are set to uninitialized values.
X */
X
X sp->sp_warn = -1;
X sp->sp_inact = -1;
X sp->sp_expire = -1;
X sp->sp_flag = -1;
X}
X
X/*
X * isexpired - determine if account is expired yet
X *
X * isexpired calculates the expiration date based on the
X * password expiration criteria.
X */
X
Xint
Xisexpired (pw, sp)
Xstruct passwd *pw;
Xstruct spwd *sp;
X{
X long clock;
X
X clock = time ((time_t *) 0) / (DAY/SCALE);
X
X /*
X * Quick and easy - there is an expired account field
X * along with an inactive account field. Do the expired
X * one first since it is worse.
X */
X
X if (sp->sp_expire > 0 && sp->sp_expire < clock)
X return 3;
X
X if (sp->sp_inact > 0 && sp->sp_lstchg > 0 && sp->sp_max > 0 &&
X sp->sp_inact + sp->sp_lstchg + sp->sp_max < clock)
X return 2;
X
X /*
X * The last and max fields must be present for an account
X * to have an expired password. A maximum of >10000 days
X * is considered to be infinite.
X */
X
X if (sp->sp_lstchg == -1 ||
X sp->sp_max == -1 || sp->sp_max >= (10000L*SCALE))
X return 0;
X
X /*
X * Calculate today's day and the day on which the password
X * is going to expire. If that date has already passed,
X * the password has expired.
X */
X
X if (sp->sp_lstchg + sp->sp_max < clock)
X return 1;
X
X return 0;
X}
X
X/*
X * expire - force password change if password expired
X *
X * expire() calls /bin/passwd to change the user's password
X * if it has expired.
X */
X
Xint
Xexpire (pw, sp)
Xstruct passwd *pw;
Xstruct spwd *sp;
X{
X int status;
X int child;
X int pid;
X
X if (! sp)
X sp = pwd_to_spwd (pw);
X
X /*
X * See if the user's password has expired, and if so
X * force them to change their password.
X */
X
X switch (status = isexpired (pw, sp)) {
X case 0:
X return 0;
X case 1:
X printf ("Your password has expired.");
X break;
X case 2:
X printf ("Your password is inactive.");
X break;
X case 3:
X printf ("Your login has expired.");
X break;
X }
X
X /*
X * Setting the maximum valid period to less than the minimum
X * valid period means that the minimum period will never
X * occur while the password is valid, so the user can never
X * change that password.
X */
X
X if (status > 1 || sp->sp_max < sp->sp_min) {
X puts (" Contact the system administrator.\n");
X exit (1);
X }
X puts (" Choose a new one.\n");
X fflush (stdout);
X
X /*
X * Close all the files so that unauthorized access won't
X * occur. This needs to be done anyway because those files
X * might become stale after "passwd" is executed.
X */
X
X endspent ();
X endpwent ();
X endsgent ();
X endgrent ();
X
X /*
X * Execute the /bin/passwd command. The exit status will be
X * examined to see what the result is. If there are any
X * errors the routine will exit. This forces the user to
X * change their password before being able to use the account.
X */
X
X if ((pid = fork ()) == 0) {
X execl ("/bin/passwd", "passwd", pw->pw_name, (char *) 0);
X puts ("Can't execute /bin/passwd");
X exit (errno);
X } else if (pid == -1) {
X perror ("passwd");
X exit (errno);
X }
X while ((child = wait (&status)) != pid && child != -1)
X ;
X
X if (child == pid && status == 0)
X return 1;
X
X exit (1);
X}
X
X/*
X * agecheck - see if warning is needed for password expiration
X *
X * agecheck sees how many days until the user's password is going
X * to expire and warns the user of the pending password expiration.
X */
X
Xvoid
Xagecheck (pw, sp)
Xstruct passwd *pw;
Xstruct spwd *sp;
X{
X long clock = time ((long *) 0) / (DAY/SCALE);
X long remain;
X
X if (! sp)
X sp = pwd_to_spwd (pw);
X
X /*
X * The last, max, and warn fields must be supported or the
X * warning period cannot be calculated.
X */
X
X if (sp->sp_lstchg == -1 || sp->sp_max == -1 || sp->sp_warn == -1)
X return;
X
X if ((remain = (sp->sp_lstchg + sp->sp_max) - clock) <= sp->sp_warn) {
X remain /= SCALE;
X if (remain >= 0)
X printf ("Your password will expire in %d %s.\n",
X remain, remain == 1 ? "day":"days");
X }
X}
SHAR_EOF
if test 6179 -ne "`wc -c < 'age.c'`"
then
echo shar: "error transmitting 'age.c'" '(should have been 6179 characters)'
fi
fi
exit 0
# End of shell archive
--
John F. Haugh II | Distribution to | UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 255-8251 | GEnie PROHIBITED :-) | Domain: jfh at rpp386.cactus.org
"If liberals interpreted the 2nd Amendment the same way they interpret the
rest of the Constitution, gun ownership would be mandatory."
More information about the Alt.sources
mailing list