[comp.bugs.sys5] dpasswd utility

lenny@icus.islp.ny.us (Lenny Tropiano) (05/02/89)

In article <5041@b11.ingr.com> linwood@b11.UUCP (Linwood Varney) writes:
|>In article <245@chip.UUCP> mparker@chip.UUCP (M. D. Parker) writes:
|>>In a system V environment, I'd be interested in knowing how these files
|>>are used, their formats, etc.
|>
|>Actually these files are quite useful, especially if you are worried about
|>security.
|>
|>The format of the /etc/dialups file is just a list of devices on
|>separate lines that are concidered dailup ports, for example
|>"/dev/tty00".  If the port that login is running on is found in dialups
...

I wrote this a while back, and it'll be useful for those playing with
Dialup Passwords.  This should compile with most compilers, and System V
systems.  Any problems should be reported to:  lenny@icus.islp.ny.us.
"unshar" and read the README ...

-Lenny Tropiano

-- cut here  -- -- cut here  -- -- cut here  -- -- cut here  -- -- cut here  --
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README Makefile dpasswd.c
# Wrapped by lenny@icus on Tue May  2 00:19:23 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(3434 characters\)
sed "s/^X//" >README <<'END_OF_README'
X-------------------
XREADME for dpasswd:     By Lenny Tropiano (ICUS Software Systems) ...icus!lenny
X-------------------
X
XThis program was written from inspiration I got at the UNIX System V release 4.0
XSoftware Developer's conference I attended this past week in Chicago, Il.
XDuring the "Q&A" session I asked the following question:
X
XQ:	"Will the previously undocumented feature of /bin/login for
X	 Dialup Passwords be documented, as well as, having appropriate
X	 utilities to manage adding and removing dialup passwords?"
X
XA:	 No, it will remain undocumented and therefore will have nothing
X	 on the system to manage those passwords.
X
XSpending about 20 minutes, I decided to write my own.  Previously I had to
Xkludge it by adding the program/pathname to /etc/passwd, executing the
X"passwd" command and then moving the encrypted password to /etc/d_passwd.
XThis was quite a pain, especially as a system administrator.  Enclosed
Xis a program I call, "dpasswd".  It basically handles the undocumented feature
Xthat was in AT&T's UNIX System V release 2.0 and beyond (/bin/login).
X
XFor those who are unsure what I'm talking about, here's a brief explanation.
X/bin/login will look in a file called /etc/dialups for tty devices that
Xare to be declared as "dialups".  The format of the file is /dev/tty names
Xterminated by newline.   If the login tty is found in /etc/dialups, it will
Xthen go to /etc/d_passwd, and look for your "login-default shell" in there.
XThe format of this file is:
X	login_default_shell_path:encrypted_passwd:
X
XIf your shell is there, it will then prompt you for "Dialup Password:" after
Xyou enter your initial password correctly.  If you enter the dialup password
Xincorrectly, you will be denied login.
X 
XWhat you can do with this, is allow everything but /bin/sh, and /bin/ksh to
Xget in without a secondary passwords.  (This will prevent having to give
Xpeople with uucp logins another password -- you can give them one, if you
Xso desire with login shell /usr/lib/uucp/uucico).
X
XSample files are as follows:
X
X/etc/dialups:
X-------------
X/dev/tty000
X/dev/ph1
X
X/etc/d_passwd:
X--------------
X/bin/sh:xeH0weIpa941Q:
X/bin/ksh:UeH0wlIpW0gyQ:
X
XUsage:  dpasswd [-v] [-d] -p program -t terminal
X
X-v		turn verbose on
X-d		delete restriction
X-p program	add (or delete) restriction for program (use full pathname)
X-t terminal	add (or delete) restriction for terminal (don't use "/dev/")
X
Xeg.
X
X# dpasswd -t tty001 -p /bin/sh
X# dpasswd -t /dev/ph1
X# dpasswd -p /bin/ksh
X
X# dpasswd -v -t tty001
Xdpasswd: Dialup terminal restriction added for /dev/tty001.
X
X# dpasswd -v -t tty001
Xdpasswd: Terminal /dev/tty001 already found in /etc/dialups.
X
X# dpasswd -v -t ph1 -p /bin/ksh
XNew Dialup Password:
XRetype Dialup Password:
Xdpasswd: Dialup terminal restriction added for /dev/ph1.
Xdpasswd: Dialup program restriction added for /bin/ksh.
X
X# dpasswd -v -d -t ph1 -p /bin/ksh
Xdpasswd: Dialup terminal restriction removed for /dev/ph1.
Xdpasswd: Dialup program restriction removed for /bin/ksh.
X
XAppropriate diagnostics will be given for all cases (hopefully).
X
XAny problems, corrections, criticisms (only good) :-) should be directed
Xto me.
X
XLenny Tropiano             ICUS Software Systems         [w] +1 (516) 582-5525
Xlenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
X{talcott,decuac,boulder,hombre,pacbell,sbcs}!icus!lenny  attmail!icus!lenny
X        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752
END_OF_README
if test 3434 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(586 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X#
X# Makefile to compile dpasswd.c  (Dialup Password Administration)
X# By Lenny Tropiano
X# (c)1988 ICUS Software Systems  UUCP: ...icus!lenny -or- lenny@icus.islp.ny.us
X#
XCFLAGS=-O
XLDFLAGS=-s
XLIBS=
XDEST=/usr/lbin/
X#
Xall:	dpasswd
X#
Xdpasswd:  dpasswd.o
X	@echo "Loading ..."
X	$(CC) $(LDFLAGS) -o dpasswd dpasswd.o $(LIBS) 
X#
Xdpasswd.o:
X	$(CC) $(CFLAGS) -c dpasswd.c
X#
X# Need to be root for this
X#
X/usr/lbin:
X	mkdir /usr/lbin
X#
Xinstall: dpasswd /usr/lbin
X	cp dpasswd ${DEST}
X	chown root ${DEST}/dpasswd
X	chgrp bin  ${DEST}/dpasswd
X	chmod 750 ${DEST}/dpasswd
X#
Xclean:
X	rm -f dpasswd *.o core
END_OF_Makefile
if test 586 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dpasswd.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"dpasswd.c\"
else
echo shar: Extracting \"dpasswd.c\" \(5766 characters\)
sed "s/^X//" >dpasswd.c <<'END_OF_dpasswd.c'
X/***************************************************************************
X * dpasswd.c
X *
X * Program to administer the "undocumented" feature /bin/login Dialup 
X * Password's that is part of most UNIX System V releases 
X *
X * By Lenny Tropiano  ICUS Software Systems     December 4, 1988
X *
X * Permission granted to redistribute without profit in the public domain
X * only.  This header must remain in-tact as is.  This program carries
X * no warranties, express or implied, and all consequences resulting from
X * the use of this program are the sole responsibility of the user.
X *
X ***************************************************************************/
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <pwd.h>
X#include <string.h>
X
X/* 
X * preprocessor parameters 
X */
X
X#ifndef MAX_DIALUP
X#define	MAX_DIALUP	10		/* maximum # of dialups on system   */
X#endif
X
X#ifndef MAX_PROGS
X#define	MAX_PROGS	20		/* maximum # of program shells      */
X#endif
X
X#ifndef TTYLEN
X#define TTYLEN		15		/* tty device length "/dev/ttyXXX"  */
X#endif
X
X#ifndef PROGLEN
X#define PROGLEN		35		/* program pathname length          */
X#endif
X
X
X/*
X * global variables
X */
X
Xint	delete,				/* remove dialup information        */
X	verbose;			/* print verbose replies            */
Xchar	terminal[TTYLEN],		/* device to declare as dialup line */
X	program[30];			/* pathname to give dialup password */
Xchar	*thisprg;
Xstatic  char *dttyfile = "/etc/dialups";
Xstatic  char *dpswfile = "/etc/d_passwd";
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int c, errflg, chgterm, chgprog;
X	extern int optind;
X	extern char *optarg;
X	void   manage_dialup(),
X	       manage_program();
X
X
X	/* 
X	 * initialize program parameters 
X	 */
X
X	thisprg = argv[0];
X	verbose = chgterm = chgprog = 0;
X	terminal[0] = program[0] = '\0';
X	
X	/* 
X	 * read command line options
X	 */
X
X	while ((c = getopt(argc, argv, "?vdt:p:")) != EOF) {
X	    switch (c) {
X	    case 'v':
X		verbose = 1;
X		break;
X	    case 'd':
X		delete = 1;
X		break;
X	    case 't':
X		if (strchr(optarg,'/') == NULL) {
X			chgterm = 1;
X			sprintf(terminal,"/dev/%s",optarg);
X		} else
X			errflg++;
X		break;
X	    case 'p':
X		chgprog = 1;
X		sprintf(program,"%s",optarg);
X		break;
X	    case '?':
X		errflg++;
X		break;
X	    }	/* end switch */
X	} /* end while */
X
X	if (errflg || (!chgterm && !chgprog)) {
X	    fprintf(stderr,
X		"Usage: %s [-v] [-d] -p program -t terminal\n", argv[0]);
X	    exit(1);
X	}
X
X	if (chgterm)
X		manage_dialup();
X
X	if (chgprog)
X		manage_program();
X
X	exit(0);
X}
X
Xvoid manage_dialup()
X{
X	FILE *fp, *fopen(), *fdopen();
X	int  fd, found;
X	int  ttyno, i;
X	char dialtty[MAX_DIALUP][TTYLEN],
X	     buffer[TTYLEN], *fgets(), *c;
X	
X	if ((fp = fopen(dttyfile, "r")) == NULL) {
X		if ((fd = creat(dttyfile, 0644)) < 0) {
X			perror(dttyfile);
X			exit(1);
X		}
X		fp = fdopen(fd, "r");
X	}
X	found = ttyno = 0;
X	while ((fgets(buffer, TTYLEN, fp) != NULL) && ttyno < MAX_DIALUP)  {
X		c = strrchr(buffer,'\n');
X		*c = '\0';
X		if (strcmp(buffer, terminal) == 0)
X			found=ttyno+1;
X		sprintf(dialtty[ttyno++], "%s", buffer);
X	}
X	fclose(fp);
X
X	if (found && delete) {
X		if ((fp = fopen(dttyfile,"w")) == NULL) {
X			perror(dttyfile);
X			exit(1);
X		}
X		found--;
X		for (i=0;i<ttyno;i++) 
X			if (i != found)
X				fprintf(fp, "%s\n", dialtty[i]);
X		fclose(fp);
X
X		if (verbose)
X		    printf("%s: Dialup terminal restriction removed from %s.\n",
X			thisprg, terminal);
X	} else if (!found && !delete) {
X		if ((fp = fopen(dttyfile,"w")) == NULL) {
X			perror(dttyfile);
X			exit(1);
X		}
X		for (i=0;i<ttyno;i++) 
X			fprintf(fp, "%s\n", dialtty[i]);
X		fprintf(fp, "%s\n", terminal);
X		fclose(fp);
X
X		if (verbose)
X		    printf("%s: Dialup terminal restriction added for %s.\n",
X			thisprg, terminal);
X	} else if (!found && delete && verbose) 
X		printf("%s: Terminal %s not found in %s.\n",
X			thisprg, terminal, dttyfile);
X	else if (found && !delete && verbose)
X		printf("%s: Terminal %s already found in %s.\n",
X			thisprg, terminal, dttyfile);
X
X}		
X
Xvoid manage_program()
X{
X	FILE *fp, *fopen(), *fdopen();
X	int  fd, found;
X	int  bad, match;
X	int  pswno, i;
X	char dialpsw[MAX_PROGS][PROGLEN],
X	     buffer[PROGLEN], *fgets(), *c,
X	     *getpass(), *crypt(), passwd[20], retype[20];
X	
X	if ((fp = fopen(dpswfile, "r")) == NULL) {
X		if ((fd = creat(dpswfile, 0644)) < 0) {
X			perror(dpswfile);
X			exit(1);
X		}
X		fp = fdopen(fd, "r");
X	}
X	found = pswno = 0;
X	while ((fgets(buffer, PROGLEN, fp) != NULL) && pswno < MAX_PROGS)  {
X		c = strrchr(buffer,'\n');
X		*c = '\0';
X		if (strncmp(buffer, program, strlen(program)) == 0)
X			found=pswno+1;
X		sprintf(dialpsw[pswno++], "%s", buffer);
X	}
X	fclose(fp);
X
X	if (found && delete) {
X		if ((fp = fopen(dpswfile,"w")) == NULL) {
X			perror(dpswfile);
X			exit(1);
X		}
X		found--;
X		for (i=0;i<pswno;i++) 
X			if (i != found)
X				fprintf(fp, "%s\n", dialpsw[i]);
X		fclose(fp);
X
X		if (verbose)
X		    printf("%s: Dialup program restriction removed from %s.\n",
X			thisprg, program);
X	} else if (!delete) {
X		if ((fp = fopen(dpswfile,"w")) == NULL) {
X			perror(dpswfile);
X			exit(1);
X		}
X		bad = 0;
X		do {
X		    sprintf(passwd,"%s",getpass("New Dialup Password:"));
X		    sprintf(retype,"%s",getpass("Retype Dialup Password:"));
X		    if ((match = strcmp(passwd, retype)) != 0) {
X			printf("They don't match; try again.\n\n");
X			bad++;
X		    }
X		} while (match != 0 && bad < 3);
X		if (bad == 3) {
X			printf("Too many tries; try again later.\n\n");
X			return;
X		}
X
X		found--;
X		for (i=0;i<pswno;i++) 
X			if (i != found)
X				fprintf(fp, "%s\n", dialpsw[i]);
X		fprintf(fp, "%s:%s:\n", program, crypt(passwd, passwd));
X			
X		fclose(fp);
X
X		if (verbose)
X		    printf("%s: Dialup program restriction added for %s.\n",
X			thisprg, program);
X
X	} else if (!found && delete && verbose) 
X		printf("%s: Program %s not found in %s.\n",
X			thisprg, program, dpswfile);
X
X}
END_OF_dpasswd.c
if test 5766 -ne `wc -c <dpasswd.c`; then
    echo shar: \"dpasswd.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
Lenny Tropiano             ICUS Software Systems         [w] +1 (516) 582-5525
lenny@icus.islp.ny.us      Telex; 154232428 ICUS         [h] +1 (516) 968-8576
{talcott,decuac,boulder,hombre,pacbell,sbcs}!icus!lenny  attmail!icus!lenny
        ICUS Software Systems -- PO Box 1; Islip Terrace, NY  11752