unix system enhancements - restricted logins

Ian Donaldson rcodi at yabbie.rmit.oz
Sun Sep 28 05:54:11 AEST 1986


In article <4120 at brl-smoke.ARPA>, Geoffm at AFSC-HQ.arpa (USAFA) writes:
> 	2.  Modify /etc/login so that it checks a file to determine if
> 	the user is allowed to login over that line or network connection
> 	or dial-up port at that time of the day.

This could be easily accomplished by changing the shell-field of the
given users in /etc/passwd to cause a "restricted shell" to be used
instead of /bin/sh or /bin/csh.

I did basically that for this purpose.  The shell I wrote examined
a list of valid ttys for the login and if valid, exec'd /bin/csh
otherwise printed a diagnostic and exited.  Simple, and requires NO
operating system changes - just changes to /etc/passwd.

Since its so small, and probably of benefit to many, I am supplying the source.
It doesn't provide login-time restrictions - it just provides
a restriction on who can log in on which ttys.  There is plenty of
room for improvment - it was a 5 minute hack that solved a problem we
had of students logging in on certain terminals that they shouldn't have
been.  But you get the general idea...

Ian Donaldson

----- cut here ----
/*
	"Rsh" - restricted tty login to csh.

	Checks that user is logged onto a valid restricted-use tty
	before exec'ing /bin/csh.

	Restricted ttys are listed one per line in /etc/rttys; or
	if /etc/rttys is unaccessable - /dev/console is the only valid tty.

	Execs /bin/csh regardless if we are not a login-shell
	(argv[0][0] is not a '-').
*/

#define RTTY	"/etc/rttys"	/* restricted ttys */
#define	TSIZE	4096		/* max size of RTTY */

static char noshell[] = "cannot exec /bin/csh or /bin/sh\n";

char	*index();

main(argc, argv, envp)
char *argc;
char *argv[];
char *envp[];
{
	char tty[32];
	int cc, f, ok;
	char buf[TSIZE];
	register char *cp, *np;

	if(argv[0][0] != '-') {
		/*
			Not login-shell - no restrictions
		*/
		run("/bin/csh", "csh", envp);
		run("/bin/sh", "sh", envp);
		write(2, noshell, sizeof(noshell) - 1);
		exit(1);
		}

	(void) strcpy(tty, ttyname(2));

	ok = 0;
	if((f = open(RTTY, 0)) == -1) 
		ok = strcmp(tty, "/dev/console") == 0;
	else {
		cc = read(f, buf, TSIZE - 2);
		if(cc > 0) {
			cp = buf;
			buf[cc] = '\n';
			while(cp < &buf[cc]) {
				np = index(cp, '\n');
				if(cp == (char *)0)
					break;
				*np = '\0';
				if(strcmp(cp, tty) == 0) {
					ok = 1;
					break;
					}
				cp = np+1;
				}
			}
		(void) close(f);
		}

	if(ok == 0) {
		static char msg1[] =
		    "You are not permitted to log-in via this terminal port (";
		static char msg2[] = ")\n";

		(void) write(2, msg1, sizeof(msg1) - 1);
		(void) write(2, tty, strlen(tty));
		(void) write(2, msg2, sizeof(msg2) - 1);
		exit(1);
		}

	run("/bin/csh", "-csh", envp);
	run("/bin/sh", "-sh", envp);
	(void) write(2, noshell, sizeof(noshell) - 1);
	exit(1);
}

/*
	run prog with argv[0] set to argv0.  
	Alter SHELL= environ variable to be equal to prog before we exec it.
*/
run(prog, argv0, envp)
char *prog;
char *argv0;
char *envp[];
{
	char *argv[2];
	register char **env;
	char newshell[32];
	static char msg[] = "No SHELL= environment variable\n";

	argv[0] = argv0;
	argv[1] = (char *)0;

	strcpy(newshell, "SHELL=");
	strcat(newshell, prog);

	for(env = &envp[0]; *env; env++) 
		if(strncmp(*env, newshell, 6) == 0) {
			*env = newshell;
			return(execve(prog, argv, envp));
			}

	write(2, msg, sizeof(msg) - 1);
	exit(1);
	/*NOTREACHED*/
}



More information about the Comp.unix.wizards mailing list