Access -- a program to give permissions across logins

Bennett E. Todd III bet at ecsvax.UUCP
Fri Oct 17 07:24:36 AEST 1986


#!/bin/sh
# Cut above the preceeding line, or cut here if you must.
# This is a shar archive.  Extract with sh, not csh.
# The rest of this file will extract:
# README Makefile access.c regerror.c
sed 's/^X//' > README << '/*EOF'
XAccess is a program I wrote to handle a not-so-infrequent situation that
Xstandard UNIX file permissions didn't seem to address, quite. Given a
Xset of users (e.g. students in a class) which are to be protected from
Xeach other (can't read or destroy each other's homework, for example)
Xand one or more "senior" logins (e.g. the teacher of the class, TAs for
Xthe class) arrange for these (individually protected from each other)
Xlogins to all be accessible to the senior, administrative logins. The
Xsenior logins aren't to be given root permissions. I couldn't figure a
Xway to do this with the standard UNIX permissions system, so I wrote the
Xfollowing. It should be installed somewhere suid root (I'd make it owner
Xroot, in a directory that isn't world writeable, mode 6711. The setgid
Xprobably isn't necessary). It checks a file "/etc/accesstab" (shouldn't
Xbe world writeable, right) for lines of the form
X
X	regexp1:regexp2
X
XIf the requesting user's username matches regexp1, then a regsub is done
Xfrom that match onto regexp2, and the resulting pattern is matched
Xagainst the requested destination. If it matches, the program succeeds.
XOtherwise, it fails. In behavior, it is about the same as su(1) with the
Xfollowing differences:
X
X	1) Doesn't require any password
X	2) Requires a match in the accesstab file
X	3) Changes to the login home directory of the requested user.
X
X(3) above is possibly not appropriate; it turned out to be proper for
Xthe use I had for it, and didn't seem to me to be a bad idea. You can
Xrip it out if you don't like it.
X
XCaveats:  I am not sure that this isn't a serious breach of security;
XI cannot think of a way to break it, but that doesn't mean it's
Xsecure. Use at your own risk, and check it before you use it. This
Xcritter explicitly kicks holes in the UNIX security system; don't use
Xit to give any logins access to privileged logins such as root, and
Xit probably shouldn't be used for any permanent project, only for
Xtemporary undertakings. DON'T TRY TO USE IT IF YOU AREN'T COMPLETELY
XCOMFORTABLE WITH REGULAR EXPRESSIONS!!! Use completely explicit
Xregular expressions, to ensure no accidental matches; regular
Xexpression metacharacters should only be used whete the logins have a
Xsystematic format (such as class logins with a common format). A
Xreasonable use would be for a class with a teacher "deboss" with
Xclass logins "cs00" - "cs49":
X
X    deboss:cs[0-4][0-9]
X
XMake sure that not only are all logins that should be permitted
Xmatchable by the target, but that all patterns matchable by the
Xtarget are ones that are supposed to be reachable.
X
XThis program is built with Henry Spencer's V8-compatible regexp
Xlibrary, from mod.sources. Get it. It's excellent.
X
XThis program was written and tested under System V (AT&T System V
XRelease 2.0.1 3B5 Version 2); as far as I know it should be portable to
Xmost reasonably modern UNIXs.
X
X-Bennett
/*EOF
ls -l README
sed 's/^X//' > Makefile << '/*EOF'
X# MYINCL is where the include file "regexp.h" can be found, if it isn't
X# in your /usr/include
XMYINCL=$(HOME)/include
X
X# Likewise for regexp.a, if the regexp routines aren't in your libc.a
XMYLIBS=$(HOME)/lib
X
XCFLAGS=-O -I$(MYINCL)
X
Xaccess : access.o regerror.o
X	cc -O -o access access.o regerror.o $(MYLIBS)/regexp.a
/*EOF
ls -l Makefile
sed 's/^X//' > access.c << '/*EOF'
X#include <stdio.h>
X#include "regexp.h"
X/*
X * access (userid) [command]
X *
X * Scans /etc/accesstab. Accesstab format
X *
X *	regex1:regex2
X *
X * If the login name of the invoker matches regex1, then a regsub is
X * performed on regex2, and if the requested "(userid)" matches the
X * resulting string, then it does a setgid to the gid of the requested
X * "(userid)", a setuid to the appropriate userid, then exec's /bin/sh.
X * It also changes directory to the home directory of the requested userid.
X * [command], if specified, is passed to sh(1).
X */
X
Xchar *progname;
Xstatic char **shargv;
Xstatic char *nope = "permission denied";
Xstatic char *tablename = "/etc/accesstab";
X
X#ifndef ERR
X#define ERR (-1)
X#endif
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	char *source,
X		 *dest,
X		 *getlogin();
X
X	progname = argv[0];
X
X	if (argc < 2)
X		syntax();
X
X	dest = argv[1];
X	shargv = argv+1;
X
X	if ((source = getlogin()) == NULL)
X		error("Who are you?!");
X
X	if (check(source, dest))
X		doit(dest);
X	else
X		error(nope);
X}
X
Xsyntax()
X{
X	fprintf(stderr, "syntax: %s username [command]\n", progname);
X	exit(1);
X}
X
Xerror(s)
Xchar *s;
X{
X	fprintf(stderr, "%s: %s\n", progname, s);
X	exit(1);
X}
X
XFILE *efopen(name, mode)
Xchar *name, *mode;
X{
X	FILE *fp, *fopen();
X	if (fp = fopen(name, mode))
X		return(fp);
X
X	fprintf(stderr, "%s: cannot open %s\n", progname, name);
X	exit(1);
X}
X
Xcheck(s, d)
Xchar *s, *d;
X{
X	FILE *fp, *efopen();
X	char buffer[256], *ptr, destbuff[256], *strchr();
X	regexp *r_src, *r_dest, *regcomp();
X
X	fp = efopen(tablename, "r");
X	while (fgets(buffer, 256, fp)) {
X		if (strlen(buffer) < 3 || *buffer == '#' || !strchr(buffer, ':'))
X			continue;
X		while ((ptr=strchr(buffer, '\n')) || (ptr=strchr(buffer, '\r')))
X			*ptr = '\0';
X		if (!(ptr=strchr(buffer, ':')))
X			error("parse error in accesstab");
X		*ptr++ = '\0';
X		r_src = regcomp(buffer);
X		if (!regexec(r_src, s))
X			continue;
X		if (!*ptr)
X			error("bad dest expression in accesstab");
X		regsub(r_src, ptr, destbuff);
X		r_dest = regcomp(destbuff);
X		if (regexec(r_dest, d)) {
X			fclose(fp);
X			return(1);
X		}
X	}
X	fclose(fp);
X	return(0);
X}
X
X#include <pwd.h>
X
Xdoit(name)
Xchar *name;
X{
X	struct passwd *ptr, *getpwnam();
X
X	if (!(ptr=getpwnam(name)))
X		error("no such userid");
X	endpwent();
X
X	if (strcmp(name, ptr->pw_name) != 0)
X		error("wrong passwd entry returned");
X
X	if (chdir(ptr->pw_dir) == ERR)
X		error("cannot chdir");
X
X	if (setgid(ptr->pw_gid) == ERR)
X		error("cannot setgid");
X
X	if (setuid(ptr->pw_uid) == ERR)
X		error("cannot setuid");
X
X	shargv[0] = "sh";
X
X	execv("/bin/sh", shargv);
X	error("exec failed");	
X}
/*EOF
ls -l access.c
sed 's/^X//' > regerror.c << '/*EOF'
X#include <stdio.h>
X
Xextern char *progname;
X
Xvoid
Xregerror(s)
Xchar *s;
X{
X	fprintf(stderr, "%s: regexp(3): %s", progname, s);
X	exit(1);
X}
/*EOF
ls -l regerror.c
exit
-- 

Bennett Todd -- Duke Computation Center, Durham, NC 27706-7756; (919) 684-3695
UUCP: ...{decvax,seismo,philabs,ihnp4,akgua}!mcnc!ecsvax!duccpc!bet
BITNET: DBTODD at TUCC.BITNET -or- DBTODD at TUCCVM.BITNET -or- bet at ECSVAX.BITNET



More information about the Comp.sources.unix mailing list