Group Password Command [ redux ]
John F. Haugh II
jfh at rpp386.cactus.org
Wed Jun 27 00:27:48 AEST 1990
Someone noted that I neglected to include config.h for people who
don't already have the shadow login stuff. Also, there was a problem
with root setting passwords on other accounts.
This posting includes a fresh, new, gpasswd.c with the "root changes
password" bug fixed and a copy of the current config.h.
Shar and Enjoy!
--
#! /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:
# Makefile
# gpmain.c
# grent.c
# password.c
# config.h
# This archive created: Tue Jun 26 09:19:37 1990
# By: John F. Haugh II (River Parishes Programming, Austin TX)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'Makefile'" '(6678 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# Non-commercial distribution permitted. You must provide this source
X# code in any distribution. This notice must remain intact.
X#
X# @(#)Makefile 2.7 09:40:16 - Shadow password system
X#
X# @(#)Makefile 2.7 09:40:16 6/22/90
X#
XSHELL = /bin/sh
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.
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 $(PWDEF) $(AL64DEF) $(OS)
XLIBS = -lcrypt
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 $(PWDEF) $(AL64DEF) $(OS)
X# LIBS =
X# LDFLAGS = -g
X# LIBSEC = libsec.a
X
XLOBJS = lmain.o login.o env.o password.o entry.o valid.o setup.o shell.o age.o \
X pwent.o utmp.o sub.o mail.o motd.o log.o shadow.o dialup.o dialchk.o \
X ttytype.o failure.o port.o
X
XLSRCS = lmain.c login.c env.c password.c entry.c valid.c setup.c shell.c age.c \
X pwent.c utmp.c sub.c mail.c motd.c log.c shadow.c dialup.c dialchk.c \
X ttytype.c failure.c port.c
X
XSOBJS = smain.o env.o password.o entry.o suvalid.o susetup.o sushell.o \
X pwent.o susub.o mail.o motd.o sulog.o shadow.o age.o
X
XSSRCS = smain.c env.c password.c entry.c valid.c setup.c shell.c \
X pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c
X
XPOBJS = pmain.o password.o entry.o valid.o pwage.o pwent.o obscure.o shadow.o
X
XPSRCS = pmain.c password.c entry.c valid.c age.c pwent.c obscure.c shadow.c
X
XGPSRCS = gpmain.c password.c grent.c
X
XGPOBJS = gpmain.o password.o grent.o
X
XPWOBJS = pwconv.o pwent.o shadow.o pwage.o
X
XPWSRCS = pwconv.c pwent.c shadow.c age.c
X
XPWUNOBJS = pwunconv.o pwent.o shadow.o pwage.o
X
XPWUNSRCS = pwunconv.c pwent.c shadow.c age.c
X
XSULOGOBJS = sulogin.o entry.o env.o password.o pwage.o pwent.o setup.o \
X shadow.o shell.o valid.o
X
XSULOGSRCS = sulogin.c entry.c env.c password.c age.c pwent.c setup.c \
X shadow.c shell.c valid.c
X
XDBOBJS = mkpasswd.o pwent.o
X
XDBSRCS = mkpasswd.c pwent.c
X
XNGSRCS = newgrp.c shadow.c password.c
X
XNGOBJS = newgrp.o shadow.o password.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 password.c pmain.c pwconv.c pwent.c pwunconv.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
X
XFILES1 = README log.c mail.c shadow.h sulog.c Makefile entry.c obscure.c \
X setup.c sub.c config.h pmain.c sulogin.c dialup.h ttytype.c \
X port.c newgrp.c
X
XFILES2 = lastlog.h login.c motd.c password.c shell.c utmp.c age.c env.c \
X pwent.c shadow.c valid.c lmain.c smain.c pwconv.c dialup.c dialchk.c \
X pwunconv.c failure.c faillog.h faillog.c port.h gpmain.c grent.c
X
XDOCS = login.1 passwd.1 passwd.4 shadow.3 shadow.4 su.1 sulogin.8 pwconv.8 \
X pwunconv.8 faillog.8 faillog.4
X
XBINS = su login pwconv pwunconv passwd sulogin faillog newgrp gpasswd \
X mkpasswd
X
Xall: $(BINS) $(DOCS)
X
Xlibsec: shadow.o
X ar rv $(LIBSEC) shadow.o
X $(RANLIB) $(LIBSEC)
X
Xinstall: all
X strip $(BINS)
X cp login $(LOGINDIR)/login
X cp mkpasswd pwconv pwunconv sulogin /etc
X cp su passwd gpasswd faillog newgrp /bin
X cp shadow.h /usr/include
X chown root $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
X /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd
X chgrp root $(LOGINDIR)/login /etc/pwconv /etc/pwunconv /etc/sulogin \
X /bin/su /bin/passwd /bin/gpasswd /bin/newgrp /etc/mkpasswd
X chown bin /bin/faillog /usr/include/shadow.h
X chgrp bin /bin/faillog /usr/include/shadow.h
X chmod 700 /etc/pwconv /etc/pwunconv /etc/sulogin /etc/mkpasswd
X chmod 4711 $(LOGINDIR)/login /bin/su /bin/passwd /bin/gpasswd \
X /bin/newgrp
X chmod 711 /bin/faillog
X chmod 444 /usr/include/shadow.h
X
Xlint: su.L login.L pwconv.L pwunconv.L passwd.L sulogin.L faillog.L \
X newgrp.L gpasswd.L
X
Xtags: $(ALLSRCS)
X $(TAGS) $(ALLSRCS)
X
XREADME: s.README
X get s.README
X
X$(DOCS):
X get s.$@
X
Xlogin: $(LOBJS)
X $(CC) -o login $(LDFLAGS) $(LOBJS) $(LIBS)
X
Xlogin.L: $(LSRCS)
X lint $(LSRCS) > login.L
X
Xsu: $(SOBJS)
X $(CC) -o su $(LDFLAGS) $(SOBJS) $(LIBS)
X
Xsu.L: $(SSRCS)
X lint -DSU $(SSRCS) > su.L
X
Xpasswd: $(POBJS)
X $(CC) -o passwd $(LDFLAGS) $(POBJS) $(LIBS)
X
Xpasswd.L: $(PSRCS)
X lint -DPASSWD $(PSRCS) > passwd.L
X
Xgpasswd: $(GPOBJS)
X $(CC) -o gpasswd $(LDFLAGS) $(GPOBJS) $(LIBS)
X
Xgpasswd.L: $(GPSRCS)
X lint $(GPSRCS) > gpasswd.L
X
Xpwconv: $(PWOBJS)
X $(CC) -o pwconv $(LDFLAGS) $(PWOBJS) $(LIBS)
X
Xpwconv.L: $(PWSRCS)
X lint -DPASSWD $(PWSRCS) > pwconv.L
X
Xpwunconv: $(PWUNOBJS)
X $(CC) -o pwunconv $(LDFLAGS) $(PWUNOBJS) $(LIBS)
X
Xpwunconv.L: $(PWUNSRCS)
X lint -DPASSWD $(PWUNSRCS) > pwunconv.L
X
Xsulogin: $(SULOGOBJS)
X $(CC) -o sulogin $(LDFLAGS) $(SULOGOBJS) $(LIBS)
X
Xsulogin.L: $(SULOGSRCS)
X lint $(SULOGSRCS) > sulogin.L
X
Xfaillog: faillog.o
X $(CC) -o faillog $(LDFLAGS) faillog.o $(LIBS)
X
Xfaillog.L: faillog.c faillog.h config.h
X lint faillog.c > faillog.L
X
Xmkpasswd: $(DBOBJS)
X $(CC) -o mkpasswd $(LDFLAGS) $(DBOBJS) $(LIBS) -ldbm
X
Xmkpasswd.L: $(DBSRCS)
X lint $(DBSRCS) > mkpasswd.L
X
Xnewgrp: $(NGOBJS)
X $(CC) -o newgrp $(LDFLAGS) $(NGOBJS) $(LIBS)
X
Xnewgrp.L: $(NGSRCS)
X lint $(NGSRCS) > newgrp.L
X
Xsushell.o: config.h shell.c
X $(CC) -c $(CFLAGS) -DSU shell.c
X mv shell.o sushell.o
X
Xsusub.o: config.h sub.c
X cp sub.c susub.c
X $(CC) -c $(CFLAGS) -DSU susub.c
X rm susub.c
X
Xsulog.o: config.h
X
Xsusetup.o: config.h setup.c
X $(CC) -c $(CFLAGS) -DSU setup.c
X mv setup.o susetup.o
X
Xsuvalid.o: config.h valid.c
X cp valid.c suvalid.c
X $(CC) -c $(CFLAGS) -DSU suvalid.c
X rm suvalid.c
X
Xpmain.o: config.h lastlog.h shadow.h
X
Xpwage.o: age.c config.h
X cp age.c pwage.c
X $(CC) -c $(CFLAGS) -DPASSWD pwage.c
X rm pwage.c
X
Xlmain.o: config.h lastlog.h faillog.h
X
Xsmain.o: config.h lastlog.h
X
Xsetup.o: config.h
X
Xutmp.o: config.h
X
Xmail.o: config.h
X
Xmotd.o: config.h
X
Xage.o: config.h
X
Xlog.o: config.h lastlog.h
X
Xshell.o: config.h
X
Xentry.o: config.h shadow.h
X
Xshadow.o: shadow.h
X
Xdialup.o: dialup.h
X
Xdialchk.o: dialup.h config.h
X
Xvalid.o: config.h
X
Xfailure.o: faillog.h config.h
X
Xfaillog.o: faillog.h config.h
X
Xpwent.o: config.h
X
Xport.o: port.h
X
Xnewgrp.o: config.h shadow.h
X
Xclean:
X -rm -f *.o a.out core npasswd nshadow *.pag *.dir
X
Xclobber: clean
X -rm -f $(BINS) *.L
X
Xshar: login.sh.1 login.sh.2 login.sh.3
X
Xlogin.sh.1: $(FILES1)
X shar -a $(FILES1) > login.sh.1
X
Xlogin.sh.2: $(FILES2)
X shar -a $(FILES2) > login.sh.2
X
Xlogin.sh.3: $(DOCS)
X shar -a $(DOCS) > login.sh.3
SHAR_EOF
if test 6678 -ne "`wc -c < 'Makefile'`"
then
echo shar: "error transmitting 'Makefile'" '(should have been 6678 characters)'
fi
fi
echo shar: "extracting 'gpmain.c'" '(7286 characters)'
if test -f 'gpmain.c'
then
echo shar: "will not over-write existing file 'gpmain.c'"
else
sed 's/^X//' << \SHAR_EOF > 'gpmain.c'
X/*
X * Copyright 1990, John F. Haugh II
X * All rights reserved.
X *
X * Non-commercial distribution permitted. You must provide this source
X * code in any distribution. This notice must remain intact.
X */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <pwd.h>
X#include <grp.h>
X#include <fcntl.h>
X#include <signal.h>
X#include <errno.h>
X#ifndef BSD
X#include <termio.h>
X#ifdef SYS3
X#include <sys/ioctl.h>
X#endif
X#include <string.h>
X#ifndef SYS3
X#include <memory.h>
X#endif
X#else
X#include <sgtty.h>
X#include <strings.h>
X#define strchr index
X#define strrchr rindex
X#endif
X#include "config.h"
X
X#ifndef PASSLENGTH
X#define PASSLENGTH 5
X#endif
X
X#ifndef lint
Xstatic char _sccsid[] = "@(#)gpmain.c 1.3 09:19:10 6/26/90";
X#endif
X
Xchar name[BUFSIZ];
Xchar pass[BUFSIZ];
Xchar pass2[BUFSIZ];
X
Xstruct group grent;
X
Xchar *myname;
X
X#ifndef RETRIES
X#define RETRIES 3
X#endif
X
Xchar *l64a ();
Xchar *crypt ();
Xextern int errno;
Xlong a64l ();
Xvoid entry ();
Xtime_t time ();
X
X/*
X * usage - display usage message
X */
X
Xvoid
Xusage ()
X{
X fprintf (stderr, "usage: %s [ -r ] group\n", myname);
X exit (1);
X}
X
Xint
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X extern int optind;
X extern char *optarg;
X char *group;
X int flag;
X int i;
X void die ();
X char *cp;
X char *getlogin ();
X int amroot;
X int lockfd = -1;
X int remove = 0;
X int retries;
X int ruid = getuid();
X int suid = geteuid();
X long salttime;
X struct group *gr;
X struct group *getgrnam ();
X struct group *sgetgrent ();
X struct passwd *pw;
X struct passwd *getpwuid ();
X struct passwd *getpwnam ();
X FILE *ngrp;
X FILE *ogrp;
X char buf[BUFSIZ];
X char tmp[BUFSIZ];
X
X amroot = getuid () == 0;
X setuid (geteuid ());
X myname = argv[0];
X
X if (! isatty (0) || ! isatty (1))
X exit (1);
X
X die (0); /* save tty modes */
X
X signal (SIGHUP, die);
X signal (SIGINT, die);
X signal (SIGQUIT, die);
X signal (SIGTERM, die);
X
X while ((flag = getopt (argc, argv, "gr")) != EOF) {
X switch (flag) {
X case 'g': /* no-op from normal password */
X break;
X case 'r': /* remove group password */
X remove = 1;
X break;
X default:
X usage ();
X }
X }
X if (cp = getlogin ()) /* need user name */
X (void) strcpy (name, cp);
X else if (pw = getpwuid (ruid)) /* get it from password file */
X strcpy (name, pw->pw_name);
X else { /* can't find user name! */
X fprintf (stderr, "Who are you?\n");
X exit (1);
X }
X if (! (pw = getpwnam (name)))
X goto failure; /* can't get my name ... */
X
X if (! (group = argv[optind]))
X usage ();
X
X if (! (gr = getgrnam (group))) {
X fprintf (stderr, "unknown group: %s\n", group);
X exit (1);
X }
X if (! amroot) {
X if (gr->gr_mem[0] == (char *) 0)
X goto failure;
X
X if (strcmp (gr->gr_mem[0], name) != 0)
X goto failure;
X }
X if (remove) {
X if (! amroot && (gr->gr_mem[0] &&
X strcmp (name, gr->gr_mem[0]) != 0))
X goto failure;
X
X gr->gr_passwd = "";
X goto output;
X }
X printf ("Changing password for group %s\n", group);
X
X printf ("Enter new password (minimum of %d characters)\n", PASSLENGTH);
X retries = RETRIES;
Xretry:
X if (! password ("New Password:", pass))
X exit (1);
X
X if (! password ("Re-enter new password:", pass2))
X exit (1);
X
X if (strcmp (pass, pass2) != 0) {
X puts ("They don't match; try again");
X
X if (retries-- > 0)
X goto retry;
X else
X goto toomany;
X }
X (void) time (&salttime);
X salttime = ((salttime & 07777) ^ ((salttime >> 12) & 07777)) & 07777;
X grent.gr_passwd = tmp;
X strcpy (grent.gr_passwd, crypt (pass, l64a (salttime)));
X#ifdef DOUBLESIZE
X if (strlen (pass) > 8) {
X strcpy (grent.gr_passwd + 13,
X crypt (pass + 8, l64a (salttime)) + 2);
X }
X#endif
Xoutput:
X
X /*
X * Now we get to race the bad guy. I don't think he can get us.
X *
X * Ignore most reasonable signals.
X * Maybe we should ignore more? He can't hurt us until the end.
X *
X * Get a lock file.
X *
X * Copy first part of password file to new file.
X * Illegal lines are copied verbatim.
X * File permissions are r--r--r--, owner root, group root.
X *
X * Output the new entry.
X * Only fields in struct passwd are output.
X *
X * Copy the rest of the file verbatim.
X *
X * Rename (link, unlink) password file to backup.
X * Kill me now and nothing changes or no one gets in.
X *
X * Rename (link, unlink) temporary file to password file.
X * Kill me now and no one gets in or lock is left.
X *
X * Remove locking file.
X *
X * That's all folks ...
X */
X
X signal (SIGHUP, SIG_IGN);
X signal (SIGINT, SIG_IGN);
X signal (SIGQUIT, SIG_IGN);
X signal (SIGTERM, SIG_IGN);
X
X ulimit (30000); /* prevent any funny business */
X umask (0); /* get new files modes correct */
X#ifndef NDEBUG
X if ((lockfd = open (".grplock", O_RDONLY|O_CREAT|O_EXCL), 0444) == -1)
X#else
X if ((lockfd = open (GRPLOCK, O_RDONLY|O_CREAT|O_EXCL), 0444) == -1)
X#endif /* NDEBUG */
X {
X puts ("Can't get lock");
X exit (1);
X }
X umask (077); /* close security holes to come ... */
X if (access (NGRPFILE, 0) == 0 && unlink (NGRPFILE) == -1)
X goto failure;
X
X#ifndef NDEBUG
X if ((ngrp = fopen ("ngroup", "w")) == (FILE *) 0)
X#else
X umask (077); /* no permissions for non-roots */
X
X if ((ngrp = fopen (NGRPFILE, "w")) == (FILE *) 0)
X#endif /* NDEBUG */
X goto failure;
X
X#ifndef NDEBUG
X chmod (NGRPFILE, 0444); /* lets have some security here ... */
X chown (NGRPFILE, 0, 0); /* ... and keep the bad guy away */
X#endif /* NDEBUG */
X if ((ogrp = fopen (GRPFILE, "r")) == (FILE *) 0)
X goto failure;
X
X while (fgets (buf, sizeof buf, ogrp) != (char *) 0) {
X if (buf[0] == '#' || ! (gr = sgetgrent (buf))) {
X fputs (buf, ngrp);
X } else if (strcmp (gr->gr_name, group) != 0)
X fputs (buf, ngrp);
X else
X break;
X }
X if (gr) {
X (void) fprintf (ngrp, "%s:%s:%d%s",
X gr->gr_name,
X grent.gr_passwd ? grent.gr_passwd:"x",
X gr->gr_gid, strrchr (buf, ':'));
X
X while (fgets (buf, BUFSIZ, ogrp) != (char *) 0)
X fputs (buf, ngrp);
X }
X if (ferror (ngrp)) {
X perror (NGRPFILE);
X if (unlink (NGRPFILE) || unlink (GRPLOCK))
X fputs ("Help!\n", stderr);
X
X exit (1);
X }
X fflush (ngrp);
X fclose (ngrp);
X#ifdef NDEBUG
X chmod (NGRPFILE, 0644);
X if (unlink (OGRPFILE) == -1) {
X if (errno != ENOENT) {
X puts ("Can't unlink backup file");
X goto unlock;
X }
X }
X if (link (GRPFILE, OGRPFILE) || unlink (GRPFILE)) {
X puts ("Can't save backup file");
X goto unlock;
X }
X#ifndef BSD
X if (link (NGRPFILE, GRPFILE) || unlink (NGRPFILE))
X#else
X if (rename (NGRPFILE, GRPFILE))
X#endif
X {
X puts ("Can't rename new file");
X goto unlock;
X }
X#endif /* NDEBUG */
X#ifndef NDEBUG
X (void) unlink (".grplock");
X#else
X (void) unlink (GRPLOCK);
X#endif
X exit (0);
X /*NOTREACHED*/
X
Xfailure:
X puts ("Permission denied.");
Xunlock:
X if (lockfd >= 0)
X (void) unlink (GRPLOCK);
X
X (void) unlink (NGRPFILE);
X exit (1);
X /*NOTREACHED*/
X
Xtoomany:
X puts ("Too many tries; try again later.");
X exit (1);
X /*NOTREACHED*/
X}
X
X/*
X * die - set or reset termio modes.
X *
X * die() is called before processing begins. signal() is then
X * called with die() as the signal handler. If signal later
X * calls die() with a signal number, the terminal modes are
X * then reset.
X */
X
Xvoid die (killed)
Xint killed;
X{
X#ifdef BSD
X static struct sgtty sgtty;
X
X if (killed)
X stty (0, &sgtty);
X else
X gtty (0, &sgtty);
X#else
X static struct termio sgtty;
X
X if (killed)
X ioctl (0, TCSETA, &sgtty);
X else
X ioctl (0, TCGETA, &sgtty);
X#endif
X if (killed) {
X putchar ('\n');
X fflush (stdout);
X exit (killed);
X }
X}
SHAR_EOF
if test 7286 -ne "`wc -c < 'gpmain.c'`"
then
echo shar: "error transmitting 'gpmain.c'" '(should have been 7286 characters)'
fi
fi
echo shar: "extracting 'grent.c'" '(1297 characters)'
if test -f 'grent.c'
then
echo shar: "will not over-write existing file 'grent.c'"
else
sed 's/^X//' << \SHAR_EOF > 'grent.c'
X/*
X * Copyright 1990, John F. Haugh II
X * All rights reserved.
X *
X * Non-commercial distribution permitted. You must provide this source
X * code in any distribution. This notice must remain intact.
X */
X
X#include <stdio.h>
X#include <grp.h>
X#include <string.h>
X#include "config.h"
X#ifdef DBM
X#include <dbm.h>
X#endif
X
X#ifndef lint
Xstatic char _sccsid[] = "@(#)grent.c 1.1 08:14:07 6/20/90";
X#endif
X
X#define NFIELDS 4
X#define MAXMEM 1024
X
Xstatic char grpbuf[4*BUFSIZ];
Xstatic char *grpfields[NFIELDS];
Xstatic char *members[MAXMEM+1];
X
Xstatic char **
Xlist (s)
Xchar *s;
X{
X int nmembers = 0;
X
X while (*s) {
X members[nmembers++] = s;
X if (s = strchr (s, ','))
X *s++ = '\0';
X }
X members[nmembers] = (char *) 0;
X return members;
X}
X
Xstruct group *sgetgrent (buf)
Xchar *buf;
X{
X int i;
X char *cp;
X static struct group grent;
X
X strncpy (grpbuf, buf, sizeof grpbuf);
X grpbuf[sizeof grpbuf - 1] = '\0';
X if (cp = strrchr (grpbuf, '\n'))
X *cp = '\0';
X
X for (cp = grpbuf, i = 0;i < NFIELDS && cp;i++) {
X grpfields[i] = cp;
X if (cp = strchr (cp, ':'))
X *cp++ = 0;
X }
X if (i < (NFIELDS-1) || *grpfields[2] == '\0')
X return ((struct group *) 0);
X
X grent.gr_name = grpfields[0];
X grent.gr_passwd = grpfields[1];
X grent.gr_gid = atoi (grpfields[2]);
X grent.gr_mem = list (grpfields[3]);
X
X return (&grent);
X}
SHAR_EOF
if test 1297 -ne "`wc -c < 'grent.c'`"
then
echo shar: "error transmitting 'grent.c'" '(should have been 1297 characters)'
fi
fi
echo shar: "extracting 'password.c'" '(1939 characters)'
if test -f 'password.c'
then
echo shar: "will not over-write existing file 'password.c'"
else
sed 's/^X//' << \SHAR_EOF > 'password.c'
X/*
X * Copyright 1988,1989,1990, John F. Haugh II
X * All rights reserved.
X *
X * Non-commercial distribution permitted. You must provide this source
X * code in any distribution. This notice must remain intact.
X */
X
X#include <stdio.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#ifndef BSD
X#include <termio.h>
X#else
X#include <sgtty.h>
X#endif
X
X#include <fcntl.h>
X
X/*
X * password - prompt for password and return entry
X *
X * Need to fake up getpass(). Returns TRUE if a password
X * was successfully input, and FALSE otherwise, including
X * EOF on input or ioctl() failure. pass is not modified
X * on failure. The input length limit may be set by
X * changing the value of PASSLIMIT.
X */
X
X#ifndef lint
Xstatic char _sccsid[] = "@(#)password.c 2.2 09:38:59 6/22/90";
X#endif
X
X#define PASSLIMIT 20
X
Xint password (prompt, pass)
Xchar *prompt;
Xchar *pass;
X{
X char buf[BUFSIZ];
X char *cp;
X int eof;
X int ttyopened = 0;
X#ifndef BSD
X struct termio termio;
X struct termio save;
X#else
X struct sgttyb termio ;
X struct sgttyb save ;
X#endif
X FILE *fp;
X
X if ((fp = fopen ("/dev/tty", "r")) == (FILE *) 0)
X fp = stdin;
X else
X ttyopened = 1;
X
X#ifndef BSD
X if (ioctl (fileno (fp), TCGETA, &termio))
X return (0);
X#else
X if ( gtty( fileno(fp), &termio ) )
X return (0);
X#endif
X
X save = termio;
X#ifndef BSD
X termio.c_lflag &= ~(ECHO|ECHOE|ECHOK);
X ioctl (fileno (fp), TCSETAF, &termio);
X#else
X termio.sg_flags &= ~ECHO ;
X stty( fileno( fp ), termio ) ;
X#endif
X
X fputs (prompt, stdout);
X eof = fgets (buf, BUFSIZ, fp) == (char *) 0 || feof (fp) || ferror (fp);
X putchar ('\n');
X
X#ifndef BSD
X ioctl (fileno (fp), TCSETAF, &save);
X#else
X stty( fileno( fp ), save ) ;
X#endif
X
X if (! eof) {
X buf[PASSLIMIT] = '\0';
X if ((cp = strchr (buf, '\n')) || (cp = strchr (buf, '\r')))
X *cp = '\0';
X
X (void) strcpy (pass, buf);
X }
X if (ttyopened)
X fclose (fp);
X
X return (! eof);
X}
SHAR_EOF
if test 1939 -ne "`wc -c < 'password.c'`"
then
echo shar: "error transmitting 'password.c'" '(should have been 1939 characters)'
fi
fi
echo shar: "extracting 'config.h'" '(5246 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 * Configuration file for login.
X *
X * @(#)config.h 2.2 00:22:54 5/25/90
X */
X
X/*
X * Define DIALUP to use dialup password files
X */
X
X#define DIALUP
X
X/*
X * Define SHADOWPWD to use shadow [ unreadable ] password file
X */
X
X#define SHADOWPWD
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 */
X
X#define AGING
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.
X */
X
X#define FAILLOG
X#define FTMP "/etc/ftmp"
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 * 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/.pwdlock"
X#define GRPLOCK "/etc/.grplock"
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 NEED_AL64 /* Define if library does not include a64l() */
SHAR_EOF
if test 5246 -ne "`wc -c < 'config.h'`"
then
echo shar: "error transmitting 'config.h'" '(should have been 5246 characters)'
fi
fi
exit 0
# End of shell archive
--
John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832 Domain: jfh at rpp386.cactus.org
Proud Pilot of RS/6000 Serial #1472
More information about the Alt.sources
mailing list