X-Git-Url: https://git.distorted.org.uk/~mdw/shells/blobdiff_plain/ed36b0a2916c0fe31f7d0779ea758c358db85fc2..HEAD:/chrootsh.c diff --git a/chrootsh.c b/chrootsh.c index 2dfa52b..1a56e00 100644 --- a/chrootsh.c +++ b/chrootsh.c @@ -1,39 +1,29 @@ /* -*-c-*- * - * $Id: chrootsh.c,v 1.1 1999/04/20 00:19:04 mdw Exp $ + * $Id$ * * Chroot gaol shell * - * (c) 1999 EBI + * (c) 1999 Mark Wooding */ /*----- Licensing notice --------------------------------------------------* * - * This file is part of Chroot shell. - * - * chrootsh is free software; you can redistribute it and/or modify + * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * chrootsh is distributed in the hope that it will be useful, + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with chrootsh; if not, write to the Free Software Foundation, + * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/*----- Revision history --------------------------------------------------* - * - * $Log: chrootsh.c,v $ - * Revision 1.1 1999/04/20 00:19:04 mdw - * Initial revision - * - */ - /*----- Header files ------------------------------------------------------*/ #include @@ -43,6 +33,7 @@ #include #include +#include #include extern char **environ; @@ -59,6 +50,7 @@ static void *xmalloc(size_t sz) { void *p = malloc(sz); if (!p) { + setuid(getuid()); fprintf(stderr, "%s: not enough memory\n", quis); exit(EXIT_FAILURE); } @@ -77,6 +69,7 @@ int main(int argc, char *argv[]) { struct passwd *pw; uid_t me = getuid(); + char *myname; char **env; char **av; @@ -89,21 +82,32 @@ int main(int argc, char *argv[]) if (*q == '/') p = q + 1; } + if (*p == '-') + p++; quis = p; + openlog(quis, LOG_PID | LOG_NDELAY, LOG_DAEMON); } /* --- Check the user is meant to be chrooted --- */ - pw = getpwuid(me); - if (!pw) { - fprintf(stderr, "%s: you don't exist. Go away.\n", quis); - exit(EXIT_FAILURE); - } - if (strcmp(pw->pw_shell, CHROOTSH_PATH) != 0) { - fprintf(stderr, "%s: you aren't a chrooted user\n", quis); - exit(EXIT_FAILURE); + { + uid_t eff = geteuid(); + + setreuid(eff, me); + pw = getpwuid(me); + if (!pw) { + syslog(LOG_ERR, "executed by non-existant user (uid = %i)", (int)me); + fprintf(stderr, "%s: you don't exist. Go away.\n", quis); + exit(EXIT_FAILURE); + } + if (strcmp(pw->pw_shell, CHROOTSH_PATH) != 0) { + syslog(LOG_ERR, "executed by non-chrooted user `%s'", pw->pw_name); + fprintf(stderr, "%s: you aren't a chrooted user\n", quis); + exit(EXIT_FAILURE); + } + endpwent(); + setreuid(me, eff); } - endpwent(); /* --- Chroot the user --- */ @@ -114,7 +118,10 @@ int main(int argc, char *argv[]) *q = 0; if (chdir(p) || chroot(p)) { - fprintf(stderr, "%s: couldn't call chroot: %s", quis, strerror(errno)); + int e = errno; + syslog(LOG_ERR, "error entering chroot gaol: %m"); + setuid(me); + fprintf(stderr, "%s: couldn't call chroot: %s\n", quis, strerror(e)); exit(EXIT_FAILURE); } setuid(me); @@ -123,21 +130,21 @@ int main(int argc, char *argv[]) /* --- Read the new password block --- */ - { - char *p = xstrdup(pw->pw_name); - pw = getpwnam(p); - free(p); - if (!pw) { - fprintf(stderr, "%s: you don't exist in the gaol\n", quis); - exit(EXIT_FAILURE); - } - endpwent(); + myname = xstrdup(pw->pw_name); + pw = getpwnam(myname); + if (!pw) { + syslog(LOG_ERR, + "configuration error: user `%s' not defined in gaol", myname); + fprintf(stderr, "%s: you don't exist in the gaol\n", quis); + exit(EXIT_FAILURE); } + endpwent(); /* --- Now fiddle with environment strings and suchlike --- */ { size_t n; + char **homevar = 0; for (n = 0; environ[n]; n++) ; env = xmalloc((n + 1) * sizeof(char *)); @@ -146,6 +153,7 @@ int main(int argc, char *argv[]) if (strncmp(environ[n], "HOME=", 5) == 0) { char *p = xmalloc(6 + strlen(pw->pw_dir)); sprintf(p, "HOME=%s", pw->pw_dir); + homevar = &env[n]; env[n] = p; } else if (strncmp(environ[n], "SHELL=", 6) == 0) { char *p = xmalloc(7 + strlen(pw->pw_shell)); @@ -155,6 +163,16 @@ int main(int argc, char *argv[]) env[n] = environ[n]; } env[n] = 0; + + /* --- Change directory (again) --- */ + + if (chdir(pw->pw_dir)) { + if (homevar) { + free(*homevar); + *homevar = "HOME=/"; + } + fprintf(stderr, "No directory, logging in with HOME=/\n"); + } } /* --- Finally, sort the argument list --- */ @@ -181,17 +199,14 @@ int main(int argc, char *argv[]) av[i] = argv[i]; } - /* --- Change directory (again) --- */ - - if (chdir(pw->pw_dir)) - fprintf(stderr, "No directory, logging in with HOME=/\n"); - /* --- Run the real shell --- */ + syslog(LOG_INFO, "chroot user `%s' logged in ok", myname); + closelog(); execve(pw->pw_shell, av, env); - fprintf(stderr, "%s: couldn't exec `%s': %s", + fprintf(stderr, "%s: couldn't exec `%s': %s\n", quis, pw->pw_shell, strerror(errno)); return (EXIT_FAILURE); } - + /*----- That's all, folks -------------------------------------------------*/