Shadow Password Suite (part 4 of 5)
John F Haugh II
jfh at rpp386.cactus.org
Thu Dec 13 05:48:49 AEST 1990
#! /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:
# gpmain.c
# chage.c
# pwent.c
# valid.c
# setup.c
# entry.c
# ttytype.c
# port.h
# grent.c
# motd.c
# dialup.h
# This archive created: Wed Dec 12 12:37:13 1990
# By: John F Haugh II (River Parishes Programming, Austin TX)
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'gpmain.c'" '(9373 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 2.1 00:44:03 11/28/90";
X#endif
X
Xchar name[BUFSIZ];
Xchar pass[BUFSIZ];
Xchar pass2[BUFSIZ];
X
Xstruct group grent;
X
Xchar *myname;
Xchar *user;
Xchar *group;
Xint aflg;
Xint dflg;
Xint rflg;
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 fprintf (stderr, " %s [ -a user ] group\n", myname);
X fprintf (stderr, " %s [ -d user ] group\n", myname);
X exit (1);
X}
X
Xchar **
Xadd_list (list, member)
Xchar **list;
Xchar *member;
X{
X int i;
X int found = 0;
X char **tmp;
X
X for (i = 0;!found && list[i] != (char *) 0;i++)
X if (strcmp (list[i], member) == 0)
X found++;
X
X tmp = (char **) malloc ((i + 2) * sizeof member);
X
X for (i = 0;list[i] != (char *) 0;i++)
X tmp[i] = list[i];
X
X if (! found) {
X tmp[i++] = strdup (member);
X tmp[i] = (char *) 0;
X }
X return tmp;
X}
X
Xchar **
Xdel_list (list, member)
Xchar **list;
Xchar *member;
X{
X int i, j;
X char **tmp;
X
X for (i = 0;list[i] != (char *) 0;i++)
X ;
X
X tmp = (char **) malloc ((i + 1) * sizeof member);
X
X for (j = i = 0;list[i] != (char *) 0;i++)
X if (strcmp (list[i], member) == 0)
X tmp[j++] = list[i];
X
X tmp[j] = (char *) 0;
X
X return tmp;
X}
X
Xint
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X extern int optind;
X extern char *optarg;
X int flag;
X int i;
X void die ();
X char *cp;
X char *getlogin ();
X int amroot;
X int lockfd = -1;
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, "a:d:gr")) != EOF) {
X switch (flag) {
X case 'a': /* add a user */
X aflg++;
X user = optarg;
X break;
X case 'd':
X dflg++;
X user = optarg;
X break;
X case 'g': /* no-op from normal password */
X break;
X case 'r': /* remove group password */
X rflg++;
X break;
X default:
X usage ();
X }
X }
X if (aflg + dflg + rflg > 1)
X usage ();
X
X if ((cp = getlogin ()) && (pw = getpwnam (cp)) && pw->pw_uid == ruid) {
X /* 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 grent = *gr;
X grent.gr_name = strdup (gr->gr_name);
X grent.gr_passwd = strdup (gr->gr_passwd);
X
X for (i = 0;gr->gr_mem[i];i++)
X ;
X grent.gr_mem = (char **) malloc ((i + 1) * sizeof (char *));
X for (i = 0;gr->gr_mem[i];i++)
X grent.gr_mem[i] = strdup (gr->gr_mem[i]);
X grent.gr_mem[i] = (char *) 0;
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 (rflg) {
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 if (aflg) {
X if (! amroot && (gr->gr_mem[0] == (char *) 0 ||
X strcmp (name, gr->gr_mem[0]) != 0))
X goto failure;
X
X printf ("Adding user %s to group %s\n", user, group);
X grent.gr_mem = add_list (gr->gr_mem, user);
X goto output;
X }
X if (dflg) {
X if (! amroot && (gr->gr_mem[0] == (char *) 0 ||
X strcmp (name, gr->gr_mem[0]) != 0))
X goto failure;
X
X printf ("Removing user %s from group %s\n", user, group);
X grent.gr_mem = del_list (gr->gr_mem, user);
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 for (retries = 0;retries < 30;retries++) {
X if ((lockfd = open (GRPLOCK, O_RDONLY|O_CREAT|O_EXCL, 0)) != -1)
X break;
X
X sleep (1);
X }
X if (lockfd == -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:",
X grent.gr_name, grent.gr_passwd ? grent.gr_passwd:"x",
X grent.gr_gid);
X
X for (i = 0;grent.gr_mem[i] != (char *) 0;i++) {
X if (i)
X fputc (',', ngrp);
X fputs (grent.gr_mem[i], ngrp);
X }
X fputc ('\n', ngrp);
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 9373 -ne "`wc -c < 'gpmain.c'`"
then
echo shar: "error transmitting 'gpmain.c'" '(should have been 9373 characters)'
fi
fi
echo shar: "extracting 'chage.c'" '(10464 characters)'
if test -f 'chage.c'
then
echo shar: "will not over-write existing file 'chage.c'"
else
sed 's/^X//' << \SHAR_EOF > 'chage.c'
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#include <sys/types.h>
X#include <stdio.h>
X#include <pwd.h>
X#include <fcntl.h>
X#include <signal.h>
X#include <errno.h>
X#include <ctype.h>
X#include <time.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#ifdef SHADOWPWD
X#include "shadow.h"
X#endif
X#ifdef DBM
X#include <dbm.h>
X#endif
X
X#ifndef lint
Xstatic char _sccsid[] = "@(#)chage.c 2.3 08:59:07 11/5/90";
X#endif
X
Xchar *myname;
X
Xtime_t today;
Xchar name[BUFSIZ];
Xchar newage[10];
Xint lflg;
Xint mflg;
Xint Mflg;
Xint dflg;
X
Xstruct passwd pwent;
X#ifdef SHADOWPWD
Xstruct spwd spwd;
X#endif
Xint mindays;
Xint maxdays;
Xlong lastday;
X
Xextern int errno;
X
Xchar Usage[] =
X"Usage: %s [ -l ] [ -m min_days ] [ -M max_days ] [ -w week | -d day ] user\n";
X
X/*
X * usage - print command line syntax and exit
X */
X
Xvoid
Xusage ()
X{
X fprintf (stderr, Usage, myname);
X exit (1);
X}
X
X/*
X * change_field - change a single field if a new value is given.
X *
X * prompt the user with the name of the field being changed and the
X * current value.
X */
X
Xvoid
Xchange_field (val, prompt)
Xint *val;
Xchar *prompt;
X{
X int newval;
X char new[BUFSIZ];
X char *cp;
X
X while (1) {
X if (*val == -1)
X printf ("\t%s []: ", prompt);
X else
X printf ("\t%s [%d]: ", prompt, *val);
X
X fgets (new, BUFSIZ, stdin);
X
X if (cp = strchr (new, '\n'))
X *cp = '\0';
X else
X return;
X
X if (new[0] == '\0')
X return;
X
X newval = strtol (new, &cp, 10);
X if (cp != new && newval >= -1 && newval <= 10000) {
X *val = newval;
X return;
X }
X fprintf (stderr, "%s: illegal value: %s\n", myname, new);
X }
X}
X
X/*
X * new_fields - change the user's password aging information interactively.
X *
X * prompt the user for the two password age values. set the fields
X * from the user's response, or leave alone if nothing was entered.
X */
X
Xnew_fields ()
X{
X printf ("Enter the new value, or press return for the default\n\n");
X
X change_field (&mindays, "Minimum Password Age");
X change_field (&maxdays, "Maximum Password Age");
X change_field (&lastday, "Last Password Change");
X}
X
X/*
X * list_fields - display the current values of the expiration fields
X *
X * display the mindays, maxdays, and lastday values.
X */
X
Xlist_fields ()
X{
X struct tm *tp;
X char *cp;
X long changed;
X long expires;
X
X changed = lastday * (24L*60L*60L);
X expires = maxdays * (24L*60L*60L) + changed;
X
X printf ("Minimum:\t%d\n", mindays);
X printf ("Maximum:\t%d\n", maxdays);
X
X printf ("Last Change:\t");
X if (changed == 0) {
X printf ("Never\n");
X } else {
X tp = localtime (&changed);
X cp = asctime (tp);
X printf ("%6.6s, %4.4s\n", cp + 4, cp + 20);
X }
X
X printf ("Expires:\t");
X if (expires == 0 || maxdays == 10000) {
X printf ("Never\n");
X } else {
X tp = localtime (&expires);
X cp = asctime (tp);
X printf ("%6.6s, %4.4s\n", cp + 4, cp + 20);
X }
X}
X
X#ifdef DBM
X/*
X * update_dbm
X *
X * Updates the DBM password files, if they exist.
X */
X
Xupdate_dbm (pw)
Xstruct passwd *pw;
X{
X datum key;
X datum content;
X char data[BUFSIZ];
X int len;
X
X strcpy (data, PWDFILE);
X strcat (data, ".pag");
X if (access (data, 0))
X return;
X
X len = pw_pack (pw, data);
X content.dsize = len;
X content.dptr = data;
X
X key.dsize = strlen (pw->pw_name);
X key.dptr = pw->pw_name;
X store (key, content);
X
X key.dsize = sizeof pw->pw_uid;
X key.dptr = (char *) &pw->pw_uid;
X store (key, content);
X}
X#endif
X
Xint
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X extern int optind;
X extern char *optarg;
X void die ();
X char *cp;
X char *getlogin ();
X int amroot;
X int lockfd = -1;
X int flag;
X struct passwd *pw;
X#ifdef SHADOWPWD
X struct spwd *sp;
X#endif
X struct passwd *getpwuid ();
X struct passwd *getpwnam ();
X struct passwd *sgetpwent ();
X FILE *npwd;
X FILE *pwd;
X char buf[BUFSIZ];
X char tmp[BUFSIZ];
X
X if (myname = strchr (argv[0], '/'))
X myname++;
X else
X myname = argv[0];
X
X if (getuid () != 0) {
X fprintf (stderr, "%s: permission denied\n", myname);
X exit (1);
X }
X while ((flag = getopt (argc, argv, "lm:M:d:w:")) != EOF) {
X switch (flag) {
X case 'l':
X lflg++;
X break;
X case 'm':
X mflg++;
X mindays = strtol (optarg, 0, 10);
X break;
X case 'M':
X Mflg++;
X maxdays = strtol (optarg, 0, 10);
X break;
X case 'd':
X dflg++;
X lastday = strtol (optarg, 0, 10);
X break;
X case 'w':
X dflg++;
X lastday = strtol (optarg, 0, 10) * 7;
X break;
X default:
X usage ();
X }
X }
X if (argc != optind + 1)
X usage ();
X
X if (! (pw = getpwnam (argv[optind]))) {
X fprintf (stderr, "%s: unknown user: %s\n",
X myname, argv[optind]);
X exit (1);
X }
X if (lflg && (mflg || Mflg || dflg)) {
X fprintf (stderr, "%s: do not include \"l\" with other flags\n",
X myname);
X exit (1);
X }
X strcpy (name, pw->pw_name);
X#ifdef SHADOWPWD
X if (sp = getspnam (name)) {
X spwd = *sp;
X spwd.sp_namp = strdup (sp->sp_namp);
X spwd.sp_pwdp = strdup (sp->sp_pwdp);
X }
X#endif
X pwent = *pw;
X pwent.pw_name = strdup (pw->pw_name);
X pwent.pw_passwd = strdup (pw->pw_passwd);
X pwent.pw_age = strdup (pw->pw_age);
X pwent.pw_gecos = strdup (pw->pw_gecos);
X pwent.pw_dir = strdup (pw->pw_dir);
X pwent.pw_shell = strdup (pw->pw_shell);
X
X /*
X * Set the fields that aren't being set from the command line
X * from the password file.
X */
X
X#ifdef SHADOWPWD
X if (sp) {
X if (! Mflg)
X maxdays = spwd.sp_max;
X if (! mflg)
X mindays = spwd.sp_min;
X if (! dflg)
X lastday = spwd.sp_lstchg;
X } else
X#endif
X if (pwent.pw_age && strlen (pwent.pw_age) >= 2) {
X if (! Mflg)
X maxdays = c64i (pwent.pw_age[0]) * 7;
X if (! mflg)
X mindays = c64i (pwent.pw_age[1]) * 7;
X if (! dflg && strlen (pwent.pw_age) == 4)
X lastday = a64l (&pwent.pw_age[2]) * 7;
X }
X
X /*
X * Print out the expiration fields if the user has
X * requested the list option.
X */
X
X if (lflg) {
X list_fields ();
X exit (0);
X }
X
X /*
X * If none of the fields were changed from the command line,
X * let the user interactively change them.
X */
X
X if (! mflg && ! Mflg && ! dflg) {
X printf ("Changing the aging information for %s\n", name);
X new_fields ();
X }
X
X /*
X * Output the new password files.
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
X#ifndef NDEBUG
X if ((lockfd = open (".pwdlock", O_RDONLY|O_CREAT|O_EXCL), 0444) == -1)
X#else
X if ((lockfd = open (PWDLOCK, 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
X#ifdef SHADOWPWD
X if (sp) {
X spwd.sp_min = mindays;
X spwd.sp_max = maxdays;
X spwd.sp_lstchg = lastday;
X
X if (access (NSHADOW, 0) == 0 && unlink (NSHADOW) == -1)
X goto failure;
X
X if ((npwd = fopen (NSHADOW, "w")) == (FILE *) 0)
X goto failure;
X
X if (chmod (NSHADOW, 0400) || chown (NSHADOW, 0, 0))
X goto failure;
X
X setspent ();
X
X while (sp = getspent ()) {
X if (strcmp (sp->sp_namp, name) == 0)
X break;
X
X if (putspent (sp, npwd))
X goto failure;
X }
X (void) putspent (&spwd, npwd); /* add the new entry */
X
X while (sp = getspent ()) /* finish the other ones off */
X (void) putspent (sp, npwd);
X
X endspent ();
X
X if (ferror (npwd)) {
X perror (NSHADOW);
X if (unlink (NPWDFILE) || unlink (PWDLOCK))
X fputs ("Help!\n", stderr);
X
X exit (1);
X }
X fflush (npwd);
X fclose (npwd);
X
X if (access (OSHADOW, 0) == 0) {
X if (unlink (OSHADOW)) {
X puts ("Can't remove backup file");
X goto unlock;
X }
X }
X if (link (SHADOW, OSHADOW) || unlink (SHADOW)) {
X puts ("Can't save backup file");
X goto unlock;
X }
X #ifndef BSD
X if (link (NSHADOW, SHADOW) || unlink (NSHADOW))
X #else
X if (rename (NSHADOW, SHADOW))
X #endif
X {
X (void) unlink (OSHADOW);
X puts ("Can't rename new file");
X goto unlock;
X }
X#ifndef NDEBUG
X (void) unlink (".pwdlock");
X#else
X (void) unlink (PWDLOCK);
X#endif
X exit (0);
X /*NOTREACHED*/
X }
X#endif
X if (maxdays == -1 || mindays == -1 || lastday == -1) {
X pwent.pw_age = "";
X } else {
X if (maxdays > (63*7))
X maxdays = 63*7;
X if (mindays > (63*7))
X mindays = 63*7;
X
X newage[0] = i64c (maxdays / 7);
X newage[1] = i64c (mindays / 7);
X strcpy (&newage[2], l64a (lastday / 7));
X pwent.pw_age = newage;
X }
X#ifdef DBM
X update_dbm (&pwent);
X#endif
X if (access (NPWDFILE, 0) == 0 && unlink (NPWDFILE) == -1) {
X perror (NPWDFILE);
X exit (1);
X }
X#ifndef NDEBUG
X if ((npwd = fopen ("npasswd", "w")) == (FILE *) 0)
X#else
X umask (077); /* no permissions for non-roots */
X
X if ((npwd = fopen (NPWDFILE, "w")) == (FILE *) 0)
X#endif /* NDEBUG */
X {
X perror (NPWDFILE);
X exit (1);
X }
X#ifndef NDEBUG
X chmod (NPWDFILE, 0444); /* lets have some security here ... */
X chown (NPWDFILE, 0, 0); /* ... and keep the bad guy away */
X#endif /* NDEBUG */
X if ((pwd = fopen (PWDFILE, "r")) == (FILE *) 0) {
X perror (NPWDFILE);
X exit (1);
X }
X while (fgets (buf, BUFSIZ, pwd) != (char *) 0) {
X if (buf[0] == '#' || ! (pw = sgetpwent (buf))) {
X fputs (buf, npwd);
X } else if (strcmp (pw->pw_name, pwent.pw_name) != 0)
X fputs (buf, npwd);
X else
X break;
X }
X (void) fprintf (npwd, "%s:", pw->pw_name);
X if (pwent.pw_age && pwent.pw_age[0])
X (void) fprintf (npwd, "%s,%s:", pwent.pw_passwd, pwent.pw_age);
X else
X (void) fprintf (npwd, "%s:", pwent.pw_passwd);
X
X (void) fprintf (npwd, "%d:%d:%s:%s:%s\n",
X pwent.pw_uid, pwent.pw_gid, pwent.pw_gecos, pwent.pw_dir,
X pwent.pw_shell);
X
X while (fgets (buf, BUFSIZ, pwd) != (char *) 0)
X fputs (buf, npwd);
X
X if (ferror (npwd)) {
X perror (NPWDFILE);
X if (unlink (NPWDFILE) || unlink (PWDLOCK))
X fputs ("Help!\n", stderr);
X
X exit (1);
X }
X fflush (npwd);
X fclose (npwd);
X#ifdef NDEBUG
X chmod (NPWDFILE, 0644);
X if (unlink (OPWDFILE) == -1) {
X if (errno != ENOENT) {
X puts ("Can't unlink backup file");
X goto unlock;
X }
X }
X if (link (PWDFILE, OPWDFILE) || unlink (PWDFILE)) {
X puts ("Can't save backup file");
X goto unlock;
X }
X#ifndef BSD
X if (link (NPWDFILE, PWDFILE) || unlink (NPWDFILE))
X#else
X if (rename (NPWDFILE, PWDFILE))
X#endif
X {
X puts ("Can't rename new file");
X goto unlock;
X }
X#endif /* NDEBUG */
X#ifndef NDEBUG
X (void) unlink (".pwdlock");
X#else
X (void) unlink (PWDLOCK);
X#endif
X exit (0);
X /*NOTREACHED*/
X
Xfailure:
X puts ("Permission denied.");
Xunlock:
X if (lockfd >= 0)
X (void) unlink (PWDLOCK);
X
X (void) unlink (NPWDFILE);
X exit (1);
X /*NOTREACHED*/
X}
SHAR_EOF
if test 10464 -ne "`wc -c < 'chage.c'`"
then
echo shar: "error transmitting 'chage.c'" '(should have been 10464 characters)'
fi
fi
echo shar: "extracting 'pwent.c'" '(6808 characters)'
if test -f 'pwent.c'
then
echo shar: "will not over-write existing file 'pwent.c'"
else
sed 's/^X//' << \SHAR_EOF > 'pwent.c'
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 * Duplication is permitted for non-commercial [ profit making ]
X * purposes provided this and other copyright notices remain
X * intact.
X */
X
X#include <stdio.h>
X#include <pwd.h>
X#include <string.h>
X#include "config.h"
X
X#ifdef DBM
X#include <dbm.h>
X#endif
X
X#ifndef lint
Xstatic char _sccsid[] = "@(#)pwent.c 2.4 23:41:33 10/28/90";
X#endif
X
X#define SBUFSIZ 64
X#define NFIELDS 7
X
Xstatic FILE *pwdfp;
Xstatic char pwdbuf[BUFSIZ];
Xstatic char *pwdfile = "/etc/passwd";
X#ifdef DBM
Xstatic int dbmopened;
Xstatic int dbmerror;
X#endif
Xstatic char *pwdfields[NFIELDS];
Xstatic struct passwd pwent;
X
X/*
X * sgetpwent - convert a string to a (struct passwd)
X *
X * sgetpwent() parses a string into the parts required for a password
X * structure. Strict checking is made for the UID and GID fields and
X * presence of the correct number of colons. Any failing tests result
X * in a NULL pointer being returned.
X */
X
Xstruct passwd *sgetpwent (buf)
Xchar *buf;
X{
X int i;
X char *cp;
X
X /*
X * Copy the string to a static buffer so the pointers into
X * the password structure remain valid.
X */
X
X strncpy (pwdbuf, buf, BUFSIZ);
X pwdbuf[BUFSIZ-1] = '\0';
X
X /*
X * Save a pointer to the start of each colon separated
X * field. The fields are converted into NUL terminated strings.
X */
X
X for (cp = pwdbuf, i = 0;i < NFIELDS && cp;i++) {
X pwdfields[i] = cp;
X if (cp = strchr (cp, ':'))
X *cp++ = 0;
X }
X
X /*
X * There must be exactly NFIELDS colon separated fields or
X * the entry is invalid. Also, the UID and GID must be non-blank.
X */
X
X if (i != NFIELDS || *pwdfields[2] == '\0' || *pwdfields[3] == '\0')
X return 0;
X
X /*
X * Each of the fields is converted the appropriate data type
X * and the result assigned to the password structure. If the
X * UID or GID does not convert to an integer value, a NULL
X * pointer is returned.
X */
X
X pwent.pw_name = pwdfields[0];
X pwent.pw_passwd = pwdfields[1];
X if ((pwent.pw_uid = strtol (pwdfields[2], &cp, 10)) == 0 && *cp)
X return 0;
X
X if ((pwent.pw_gid = strtol (pwdfields[3], &cp, 10)) == 0 && *cp)
X return 0;
X
X if (cp = strchr (pwent.pw_passwd, ',')) {
X pwent.pw_age = cp + 1;
X *cp = '\0';
X } else
X pwent.pw_age = "";
X
X pwent.pw_gecos = pwdfields[4];
X pwent.pw_dir = pwdfields[5];
X pwent.pw_shell = pwdfields[6];
X
X return (&pwent);
X}
X#ifdef FGETPWENT
X/*
X * fgetpwent - get a password file entry from a stream
X *
X * fgetpwent() reads the next line from a password file formatted stream
X * and returns a pointer to the password structure for that line.
X */
X
Xstruct passwd *fgetpwent (fp)
XFILE *fp;
X{
X char buf[BUFSIZ];
X
X while (fgets (buf, BUFSIZ, fp) != (char *) 0) {
X buf[strlen (buf) - 1] = '\0';
X return (sgetpwent (buf));
X }
X return 0;
X}
X#endif
X#ifdef GETPWENT
X
X/*
X * endpwent - close a password file
X *
X * endpwent() closes the password file if open.
X */
X
Xint endpwent ()
X{
X if (pwdfp)
X if (fclose (pwdfp))
X return -1;
X
X return 0;
X}
X
X/*
X * getpwent - get a password entry from the password file
X *
X * getpwent() opens the password file, if not already opened, and reads
X * a single entry. NULL is returned if any errors are encountered reading
X * the password file.
X */
X
Xstruct passwd *getpwent ()
X{
X if (! pwdfp && setpwent ())
X return 0;
X
X return fgetpwent (pwdfp);
X}
X
X/*
X * getpwuid - locate the password entry for a given UID
X *
X * getpwuid() locates the first password file entry for the given UID.
X * If there is a valid DBM file, the DBM files are queried first for
X * the entry. Otherwise, a linear search is begun of the password file
X * searching for an entry which matches the provided UID.
X */
X
Xstruct passwd *getpwuid (uid)
Xint uid;
X{
X struct passwd *pwd;
X#ifdef DBM
X datum key;
X datum content;
X
X /*
X * Attempt to open the DBM files if they have never been opened
X * and an error has never been returned.
X */
X
X if (! dbmerror && ! dbmopened) {
X char dbmfiles[BUFSIZ];
X
X strcpy (dbmfiles, pwdfile);
X strcat (dbmfiles, ".pag");
X
X if (access (dbmfiles, 0) || dbminit (pwdfile))
X dbmerror = 1;
X else
X dbmopened = 1;
X }
X
X /*
X * If the DBM file are now open, create a key for this UID and
X * try to fetch the entry from the database. A matching record
X * will be unpacked into a static structure and returned to
X * the user.
X */
X
X if (dbmopened) {
X pwent.pw_uid = uid;
X key.dsize = sizeof pwent.pw_uid;
X key.dptr = (char *) &pwent.pw_uid;
X content = fetch (key);
X if (content.dptr != 0) {
X memcpy (pwdbuf, content.dptr, content.dsize);
X pw_unpack (pwdbuf, content.dsize, &pwent);
X return &pwent;
X }
X }
X#endif
X /*
X * Rewind the database and begin searching for an entry which
X * matches the UID. Return the entry when a match is found.
X */
X
X if (setpwent ())
X return 0;
X
X while (pwd = getpwent ())
X if (pwd->pw_uid == uid)
X return pwd;
X
X return 0;
X}
X
Xstruct passwd *getpwnam (name)
Xchar *name;
X{
X struct passwd *pwd;
X#ifdef DBM
X datum key;
X datum content;
X
X /*
X * Attempt to open the DBM files if they have never been opened
X * and an error has never been returned.
X */
X
X if (! dbmerror && ! dbmopened) {
X char dbmfiles[BUFSIZ];
X
X strcpy (dbmfiles, pwdfile);
X strcat (dbmfiles, ".pag");
X
X if (access (dbmfiles, 0) || dbminit (pwdfile))
X dbmerror = 1;
X else
X dbmopened = 1;
X }
X
X /*
X * If the DBM file are now open, create a key for this UID and
X * try to fetch the entry from the database. A matching record
X * will be unpacked into a static structure and returned to
X * the user.
X */
X
X if (dbmopened) {
X key.dsize = strlen (name);
X key.dptr = name;
X content = fetch (key);
X if (content.dptr != 0) {
X memcpy (pwdbuf, content.dptr, content.dsize);
X pw_unpack (pwdbuf, content.dsize, &pwent);
X return &pwent;
X }
X }
X#endif
X /*
X * Rewind the database and begin searching for an entry which
X * matches the name. Return the entry when a match is found.
X */
X
X if (setpwent ())
X return 0;
X
X while (pwd = getpwent ())
X if (strcmp (pwd->pw_name, name) == 0)
X return pwd;
X
X return 0;
X}
X
X/*
X * setpwent - open the password file
X *
X * setpwent() opens the system password file, and the DBM password files
X * if they are present. The system password file is rewound if it was
X * open already.
X */
X
Xint setpwent ()
X{
X if (! pwdfp) {
X if (! (pwdfp = fopen (pwdfile, "r")))
X return -1;
X } else {
X if (fseek (pwdfp, 0L, 0) != 0)
X return -1;
X }
X#ifdef DBM
X /*
X * Attempt to open the DBM files if they have never been opened
X * and an error has never been returned.
X */
X
X if (! dbmerror && ! dbmopened) {
X char dbmfiles[BUFSIZ];
X
X strcpy (dbmfiles, pwdfile);
X strcat (dbmfiles, ".pag");
X
X if (access (dbmfiles, 0) || dbminit (pwdfile))
X dbmerror = 1;
X else
X dbmopened = 1;
X }
X#endif
X return 0;
X}
X#endif
SHAR_EOF
if test 6808 -ne "`wc -c < 'pwent.c'`"
then
echo shar: "error transmitting 'pwent.c'" '(should have been 6808 characters)'
fi
fi
echo shar: "extracting 'valid.c'" '(3190 characters)'
if test -f 'valid.c'
then
echo shar: "will not over-write existing file 'valid.c'"
else
sed 's/^X//' << \SHAR_EOF > 'valid.c'
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#include <stdio.h>
X#include <pwd.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[] = "@(#)valid.c 2.4 19:24:27 7/29/90";
X#endif
X
X/*
X * valid - compare encrypted passwords
X *
X * Valid() compares the DES encrypted password from the password file
X * against the password which the user has entered after it has been
X * encrypted using the same salt as the original.
X */
X
Xint valid (password, entry)
Xchar *password;
Xstruct passwd *entry;
X{
X char *encrypt;
X char *salt;
X char *crypt ();
X char *shell;
X#ifdef DOUBLESIZE
X int firsthalf;
X int longpass;
X#endif
X
X#ifdef NOUSE
X if (entry->pw_shell && strcmp (NOUSE, entry->pw_shell) == 0)
X return (0);
X#if defined(SU) && defined (NOLOGIN)
X if (entry->pw_shell && strcmp (NOLOGIN, entry->pw_shell) == 0) {
X if (! (shell = getenv ("SHELL")))
X return 0;
X }
X#endif
X#if !defined(SU) && defined (NOLOGIN)
X if (entry->pw_shell && strcmp (NOLOGIN, entry->pw_shell) == 0)
X return 0;
X#endif
X#endif
X /*
X * Start with blank or empty password entries. Always encrypt
X * a password if no such user exists. Only if the ID exists and
X * the password is really empty do you return quickly. This
X * routine is meant to waste CPU time.
X */
X
X if (entry->pw_name &&
X (entry->pw_passwd == (char *) 0 ||
X strlen (entry->pw_passwd) == 0)) {
X if (strlen (password) == 0)
X return (1); /* user entered nothing */
X else
X return (0); /* user entered something! */
X }
X
X#ifdef DOUBLESIZE
X longpass = entry->pw_passwd && strlen (entry->pw_passwd) > 13;
X#endif
X
X /*
X * If there is no entry then we need a salt to use.
X */
X
X if (entry->pw_passwd == (char *) 0 || entry->pw_passwd[0] == '\0')
X salt = "xx";
X else
X salt = entry->pw_passwd;
X
X /*
X * Now, perform the encryption using the salt from before on
X * the users input. Since we always encrypt the string, it
X * should be very difficult to determine if the user exists by
X * looking at execution time.
X */
X
X encrypt = crypt (password, salt);
X#ifdef DOUBLESIZE
X firsthalf = entry->pw_passwd
X && strncmp (encrypt + 2, entry->pw_passwd + 2, 11) == 0;
X
X if (strlen (password) > 8)
X encrypt = crypt (password + 8, salt);
X else {
X (void) crypt (password, salt); /* waste time ... */
X encrypt = "";
X }
X#endif
X /*
X * One last time we must deal with there being no password file
X * entry for the user. We use the pw_passwd == NULL idiom to
X * cause non-existent users to not be validated. Even still,
X * we are safe because if the string were == "", any encrypted
X * string is not going to match - the output of crypt() begins
X * with the salt, which is "xx", not "".
X */
X
X#ifndef DOUBLESIZE
X if (entry->pw_passwd && strcmp (encrypt, entry->pw_passwd) == 0)
X return (1);
X else
X return (0);
X#else
X if (! longpass)
X return (firsthalf);
X
X if (entry->pw_passwd && firsthalf
X && strncmp (encrypt + 2, entry->pw_passwd + 13) == 0)
X return (1);
X else
X return (0);
X#endif
X}
SHAR_EOF
if test 3190 -ne "`wc -c < 'valid.c'`"
then
echo shar: "error transmitting 'valid.c'" '(should have been 3190 characters)'
fi
fi
echo shar: "extracting 'setup.c'" '(2514 characters)'
if test -f 'setup.c'
then
echo shar: "will not over-write existing file 'setup.c'"
else
sed 's/^X//' << \SHAR_EOF > 'setup.c'
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#include <sys/types.h>
X#include <pwd.h>
X#include <utmp.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[] = "@(#)setup.c 2.2 19:24:10 7/29/90";
X#endif
X
Xextern char home[];
Xextern char prog[];
Xextern char name[];
Xextern char mail[];
X
X#ifndef PATH
X#define PATH ":/bin:/usr/bin"
X#endif
X
X#ifndef SUPATH
X#define SUPATH ":/bin:/usr/bin:/etc"
X#endif
X
X#ifndef MAILDIR
X#define MAILDIR "/usr/spool/mail"
X#endif
X
X#ifndef TTYPERM
X#define TTYPERM 0622
X#endif
X
X#ifndef SU
Xextern struct utmp utent;
X#endif
X
X#ifdef QUOTAS
Xlong strtol ();
X#ifdef ULIMIT
Xlong ulimit ();
X#endif
X#endif
X
Xvoid addenv ();
X
Xvoid setup (info)
Xstruct passwd *info;
X{
X extern int errno;
X char logname[30];
X#ifndef SU
X char tty[30];
X#endif
X char *cp;
X int i;
X long l;
X
X#ifndef SU
X (void) strcat (strcpy (tty, "/dev/"), utent.ut_line);
X if (chown (tty, info->pw_uid, info->pw_gid) ||
X chmod (tty, TTYPERM))
X perror (tty);
X#endif
X if (chdir (info->pw_dir) == -1) {
X (void) printf ("Unable to change directory to \"%s\"\n", info->pw_dir);
X exit (errno);
X }
X#ifdef QUOTAS
X for (cp = info->pw_gecos;cp != (char *) 0;cp = strchr (cp, ',')) {
X if (*cp == ',')
X cp++;
X
X if (strncmp (cp, "pri=", 4) == 0) {
X i = atoi (cp + 4);
X if (i >= -20 && i <= 20)
X (void) nice (i);
X
X continue;
X }
X#ifdef ULIMIT
X if (strncmp (cp, "ulimit=", 7) == 0) {
X l = strtol (cp + 7, (char **) 0, 10);
X (void) ulimit (2, l);
X
X continue;
X }
X#endif
X if (strncmp (cp, "umask=", 6) == 0) {
X i = strtol (cp + 6, (char **) 0, 8) & 0777;
X (void) umask (i);
X
X continue;
X }
X }
X#endif
X if (setgid (info->pw_gid) == -1) {
X puts ("Bad group id");
X exit (errno);
X }
X#ifndef BSD
X if (setuid (info->pw_uid))
X#else
X if (setreuid (info->pw_uid, info->pw_uid))
X#endif
X {
X puts ("Bad user id");
X exit (errno);
X }
X (void) strcat (strcpy (home, "HOME="), info->pw_dir);
X addenv (home);
X
X if (info->pw_shell == (char *) 0)
X info->pw_shell = "/bin/sh";
X
X (void) strcat (strcpy (prog, "SHELL="), info->pw_shell);
X addenv (prog);
X
X if (info->pw_uid == 0)
X addenv (SUPATH);
X else
X addenv (PATH);
X
X (void) strcat (strcpy (logname, "LOGNAME="), name);
X addenv (logname);
X
X (void) strcat (strcat (strcpy (mail, "MAIL="), MAILDIR), name);
X addenv (mail);
X}
SHAR_EOF
if test 2514 -ne "`wc -c < 'setup.c'`"
then
echo shar: "error transmitting 'setup.c'" '(should have been 2514 characters)'
fi
fi
echo shar: "extracting 'entry.c'" '(2353 characters)'
if test -f 'entry.c'
then
echo shar: "will not over-write existing file 'entry.c'"
else
sed 's/^X//' << \SHAR_EOF > 'entry.c'
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#include <stdio.h>
X#include <pwd.h>
X#ifndef BSD
X#include <string.h>
X#else
X#include <strings.h>
X#define strchr index
X#define strrchr rindex
X#endif
X#include "config.h"
X#ifdef SHADOWPWD
X#include "shadow.h"
X#endif
X
X#ifndef lint
Xstatic char _sccsid[] = "@(#)entry.c 2.3 07:47:34 8/14/90";
X#endif
X
Xstruct passwd *fgetpwent ();
Xchar *malloc ();
X
Xchar *strdup (s)
Xchar *s;
X{
X char *cp;
X
X if (s == (char *) 0)
X return ((char *) 0);
X
X if (! (cp = malloc ((unsigned) strlen (s) + 1)))
X return ((char *) 0);
X
X return (strcpy (cp, s));
X}
X
Xvoid entry (name, pwent)
Xchar *name;
Xstruct passwd *pwent;
X{
X FILE *pwd;
X struct passwd *passwd;
X#ifdef SHADOWPWD
X struct spwd *spwd;
X char *l64a ();
X#endif
X char *cp;
X
X if ((pwd = fopen (PWDFILE, "r")) == (FILE *) 0) {
X pwent->pw_passwd = (char *) 0;
X return;
X }
X while (passwd = fgetpwent (pwd)) {
X if (strcmp (name, passwd->pw_name) == 0)
X break;
X }
X fclose (pwd);
X
X if (passwd == (struct passwd *) 0) {
X pwent->pw_name = (char *) 0;
X pwent->pw_passwd = (char *) 0;
X } else {
X pwent->pw_name = strdup (passwd->pw_name);
X pwent->pw_uid = passwd->pw_uid;
X pwent->pw_gid = passwd->pw_gid;
X pwent->pw_comment = (char *) 0;
X pwent->pw_gecos = strdup (passwd->pw_gecos);
X pwent->pw_dir = strdup (passwd->pw_dir);
X pwent->pw_shell = strdup (passwd->pw_shell);
X#ifdef SHADOWPWD
X setspent ();
X if (spwd = getspnam (name)) {
X pwent->pw_passwd = strdup (spwd->sp_pwdp);
X
X pwent->pw_age = malloc (5);
X
X if (spwd->sp_max > (63*7))
X spwd->sp_max = (63*7);
X if (spwd->sp_min > (63*7))
X spwd->sp_min = (63*7);
X
X pwent->pw_age[0] = i64c (spwd->sp_max / 7);
X pwent->pw_age[1] = i64c (spwd->sp_min / 7);
X
X cp = l64a (spwd->sp_lstchg / 7);
X pwent->pw_age[2] = cp[0];
X pwent->pw_age[3] = cp[1];
X
X pwent->pw_age[4] = '\0';
X
X endspent ();
X return;
X }
X endspent ();
X passwd->pw_age = pwent->pw_age = (char *) 0;
X#endif
X if (passwd->pw_passwd)
X pwent->pw_passwd = strdup (passwd->pw_passwd);
X else
X pwent->pw_passwd = (char *) 0;
X
X if (passwd->pw_age) {
X pwent->pw_age = malloc (5); /* longest legal time */
X (void) strncpy (pwent->pw_age, passwd->pw_age, 5);
X } else
X pwent->pw_age = (char *) 0;
X }
X}
SHAR_EOF
if test 2353 -ne "`wc -c < 'entry.c'`"
then
echo shar: "error transmitting 'entry.c'" '(should have been 2353 characters)'
fi
fi
echo shar: "extracting 'ttytype.c'" '(1125 characters)'
if test -f 'ttytype.c'
then
echo shar: "will not over-write existing file 'ttytype.c'"
else
sed 's/^X//' << \SHAR_EOF > 'ttytype.c'
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#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#include "config.h"
X
X#ifdef TTYTYPE
X#ifndef lint
Xstatic char _sccsid[] = "@(#)ttytype.c 2.2 19:24:24 7/29/90";
X#endif
X
X/*
X * ttytype - set ttytype from port to terminal type mapping database
X */
X
Xvoid ttytype (line)
Xchar *line;
X{
X FILE *fp;
X char buf[BUFSIZ];
X char termvar[BUFSIZ];
X char *cp;
X char *type;
X char *port;
X char *getenv ();
X
X if (getenv ("TERM"))
X return;
X
X if (! (fp = fopen (TTYTYPE, "r")))
X return;
X
X while (fgets (buf, BUFSIZ, fp)) {
X if (buf[0] == '#')
X continue;
X
X if (cp = strchr (buf, '\n'))
X *cp = '\0';
X
X if ((type = strtok (buf, " \t"))
X && (port = strtok ((char *) 0, " \t"))) {
X if (strcmp (line, port) == 0)
X break;
X }
X }
X if (! feof (fp) && ! ferror (fp)) {
X strcat (strcpy (termvar, "TERM="), type);
X addenv (termvar);
X }
X fclose (fp);
X}
X#endif
SHAR_EOF
if test 1125 -ne "`wc -c < 'ttytype.c'`"
then
echo shar: "error transmitting 'ttytype.c'" '(should have been 1125 characters)'
fi
fi
echo shar: "extracting 'port.h'" '(1459 characters)'
if test -f 'port.h'
then
echo shar: "will not over-write existing file 'port.h'"
else
sed 's/^X//' << \SHAR_EOF > 'port.h'
X/*
X * Copyright 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 * port.h - structure of /etc/porttime
X *
X * @(#)port.h 1.3 08:26:37 8/20/90
X *
X * Each entry in /etc/porttime consists of a TTY device
X * name or "*" to indicate all TTY devices, followed by
X * a list of 1 or more user IDs or "*" to indicate all
X * user names, followed by a list of zero or more valid
X * login times. Login time entries consist of zero or
X * more day names (Su, Mo, Tu, We, Th, Fr, Sa, Wk, Al)
X * followed by a pair of time values in HHMM format
X * separated by a "-".
X */
X
X/*
X * PORTS - Name of system port access time file.
X * PORT_IDS - Allowable number of IDs per entry.
X * PORT_TIMES - Allowable number of time entries per entry.
X * PORT_DAY - Day of the week to a bit value (0 = Sunday).
X */
X
X#define PORTS "/etc/porttime"
X#define PORT_IDS 64
X#define PORT_TIMES 24
X#define PORT_DAY(day) (1<<(day))
X
X/*
X * pt_name - pointer to device name in /dev/
X * pt_users - pointer to array of applicable user IDs.
X * pt_times - pointer to list of allowable time periods.
X */
X
Xstruct port {
X char *pt_name;
X char **pt_users;
X struct pt_time *pt_times;
X};
X
X/*
X * t_days - bit array for each day of the week (0 = Sunday)
X * t_start - starting time for this entry
X * t_end - ending time for this entry
X */
X
Xstruct pt_time {
X short t_days;
X short t_start;
X short t_end;
X};
SHAR_EOF
if test 1459 -ne "`wc -c < 'port.h'`"
then
echo shar: "error transmitting 'port.h'" '(should have been 1459 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 'motd.c'" '(750 characters)'
if test -f 'motd.c'
then
echo shar: "will not over-write existing file 'motd.c'"
else
sed 's/^X//' << \SHAR_EOF > 'motd.c'
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#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#include "config.h"
X
X#ifndef lint
Xstatic char _sccsid[] = "@(#)motd.c 2.2 19:23:58 7/29/90";
X#endif
X
Xextern char home[];
X#ifdef HUSHLOGIN
Xextern int hushed;
X#endif
X
X#ifdef MOTD
Xvoid motd ()
X{
X FILE *fp;
X register int c;
X
X#ifdef HUSHLOGIN
X if (hushed)
X return;
X#endif
X if ((fp = fopen ("/etc/motd", "r")) == (FILE *) 0)
X return;
X
X while ((c = getc (fp)) != EOF)
X putchar (c);
X
X fclose (fp);
X fflush (stdout);
X}
X#endif
SHAR_EOF
if test 750 -ne "`wc -c < 'motd.c'`"
then
echo shar: "error transmitting 'motd.c'" '(should have been 750 characters)'
fi
fi
echo shar: "extracting 'dialup.h'" '(928 characters)'
if test -f 'dialup.h'
then
echo shar: "will not over-write existing file 'dialup.h'"
else
sed 's/^X//' << \SHAR_EOF > 'dialup.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 * Structure of d_passwd file
X *
X * The d_passwd file contains the names of login shells which require
X * dialup passwords. Each line contains the fully qualified path name
X * for the shell, followed by an optional password. Each field is
X * separated by a ':'.
X *
X * Structure of the dialups file
X *
X * The dialups file contains the names of ports which may be dialup
X * lines. Each line consists of the last component of the path
X * name. Any leading directory names are removed.
X *
X * @(#)dialup.h 2.2 19:23:40 7/29/90
X */
X
Xstruct dialup {
X char *du_shell;
X char *du_passwd;
X};
X
Xvoid setduent ();
Xvoid endduent ();
Xstruct dialup *getduent ();
Xstruct dialup *getdushell ();
X
X#define DIALPWD "/etc/d_passwd"
X#define DIALUPS "/etc/dialups"
SHAR_EOF
if test 928 -ne "`wc -c < 'dialup.h'`"
then
echo shar: "error transmitting 'dialup.h'" '(should have been 928 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
More information about the Alt.sources
mailing list