Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!haven.umd.edu!uunet!news!demon!pizzabox.demon.co.uk!gtoal
Newsgroups: comp.os.386bsd.questions
From: gtoal@pizzabox.demon.co.uk ("gtoal)
Reply-To: Graham Toal <gtoal@gtoal.com>
Subject: Restricted root shells: termcap problem?
Date: Tue, 20 Jul 1993 22:35:40 +0000
Message-ID: <9307202235.AA10295@pizzabox.demon.co.uk>
Sender: usenet@demon.co.uk
Lines: 143
I've been experimenting with creating a shell that runs in a restricted
root. (No special reason, just wanted to learn more unix stuff)
I've got it set up pretty well, but there's one *strange* problem...
when I run programs (say irc for example) that need termcap information,
they say things like 'No termcap entry for vt100.' There clearly *is*
a termcap entry - I can see it in /etc/termcap by grepping for it.
Any ideas what's afoot?
Below is the program that I've set to be the shell on the guest account.
I've created a /fakeroot directory which pretends to be /, and inside
it I've created dirs /etc /usr/local/bin etc etc - inside those dirs
I've done ln /etc/* . (from su) to create copies of all the real files.
I create the whole of /dev on the fly each time I enter, plus a couple
of .db files are relinked to make sure they're up to date to provide
info for 'who' etc. See for yourself:
/* su; cc -o csh csh.c; chmod 4755 csh */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define GUEST_UID 314
#define GUEST_GID 314
int main(int argc, char **argv)
{
FILE *cshrc, *fcshrc;
FILE *login, *flogin;
char *margv[2];
int i, c;
int tty;
char *ttypx;
char fakettypx[128];
unlink("/fakeroot/var/run/utmp");
link("/var/run/utmp", "/fakeroot/var/run/utmp");
unlink("/fakeroot/var/run/dev.db");
link("/var/run/dev.db", "/fakeroot/var/run/dev.db");
tty = fileno(stdin);
ttypx = ttyname(tty);
if (ttypx == NULL) exit(1);
if (*ttypx != '/') exit(1);
sprintf(fakettypx, "/fakeroot%s", ttypx);
unlink(fakettypx);
for (i = '0'; i <= '9'; i++) {
sprintf(fakettypx, "/fakeroot/dev/ttyp%c", i);
unlink(fakettypx);
}
for (i = 'a'; i <= 'f'; i++) {
sprintf(fakettypx, "/fakeroot/dev/ttyp%c", i);
unlink(fakettypx);
}
unlink("/fakeroot/dev/console");
unlink("/fakeroot/dev/cua0");
unlink("/fakeroot/dev/cua1");
unlink("/fakeroot/dev/drum");
unlink("/fakeroot/dev/fd0a");
unlink("/fakeroot/dev/fd1a");
unlink("/fakeroot/dev/klog");
unlink("/fakeroot/dev/kmem");
unlink("/fakeroot/dev/log");
unlink("/fakeroot/dev/lp");
unlink("/fakeroot/dev/lpt1");
unlink("/fakeroot/dev/mem");
unlink("/fakeroot/dev/null");
unlink("/fakeroot/dev/stderr");
unlink("/fakeroot/dev/stdin");
unlink("/fakeroot/dev/stdout");
unlink("/fakeroot/dev/tty");
unlink("/fakeroot/dev/ttyd0");
unlink("/fakeroot/dev/ttyd1");
sprintf(fakettypx, "/fakeroot%s", ttypx);
link(ttypx, fakettypx);
link("/dev/console", "/fakeroot/dev/console");
link("/dev/cua0", "/fakeroot/dev/cua0");
link("/dev/cua1", "/fakeroot/dev/cua1");
link("/dev/drum", "/fakeroot/dev/drum");
link("/dev/fd0a", "/fakeroot/dev/fd0a");
link("/dev/fd1a", "/fakeroot/dev/fd1a");
link("/dev/klog", "/fakeroot/dev/klog");
link("/dev/kmem", "/fakeroot/dev/kmem");
link("/dev/log", "/fakeroot/dev/log");
link("/dev/lp", "/fakeroot/dev/lp");
link("/dev/lpt1", "/fakeroot/dev/lpt1");
link("/dev/mem", "/fakeroot/dev/mem");
link("/dev/null", "/fakeroot/dev/null");
link("/dev/stderr", "/fakeroot/dev/stderr");
link("/dev/stdin", "/fakeroot/dev/stdin");
link("/dev/stdout", "/fakeroot/dev/stdout");
link("/dev/tty", "/fakeroot/dev/tty");
link("/dev/ttyd0", "/fakeroot/dev/ttyd0");
link("/dev/ttyd1", "/fakeroot/dev/ttyd1");
margv[0] = "-"; /* exec .login */
margv[1] = NULL;
cshrc = fopen("/home/guest/.cshrc", "rb");
if (cshrc == NULL) exit(1);
(void)remove("/fakeroot/home/guest/.cshrc");
login = fopen("/home/guest/.login", "rb");
if (login == NULL) exit(1);
(void)remove("/fakeroot/home/guest/.login");
i = chdir("/fakeroot/home/guest");
if (i != 0) exit(1);
i = chroot("/fakeroot");
if (i != 0) exit(1);
i = setgid(GUEST_GID);
if (i != 0) exit(1);
i = setuid(GUEST_UID);
if (i != 0) exit(1);
i = chdir("/home/guest");
if (i != 0) exit(1);
fcshrc = fopen("/home/guest/.cshrc", "wb");
if (fcshrc == NULL) exit(1);
for (;;) {
c = fgetc(cshrc);
if (c == EOF) break;
fputc(c, fcshrc);
}
fclose(cshrc); fclose(fcshrc);
flogin = fopen("/home/guest/.login", "wb");
if (flogin == NULL) exit(1);
for (;;) {
c = fgetc(login);
if (c == EOF) break;
fputc(c, flogin);
}
fclose(login); fclose(flogin);
setenv("HOME", "/home/guest", 1);
i = execv("/bin/csh", margv);
/* Shouldn't return */
exit(1);
return(1);
}
PS I've also set the guest account withboth user/gid 314, and done the
thing with /etc/shells and /etc/ftpusers to ensure that it gets a
restricted root when it logs in on ftp too. If there's anything else
I can usefully do, please tell me.