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.