From: mdw Date: Thu, 22 Apr 1999 00:30:27 +0000 (+0000) Subject: Miscellanous tidying and security fixes. Lots of thanks due to Clive X-Git-Tag: 1.0.0~5 X-Git-Url: https://git.distorted.org.uk/~mdw/shells/commitdiff_plain/a079e30ddd1bc8a2a883a765311f3af0cfb08cb1 Miscellanous tidying and security fixes. Lots of thanks due to Clive Jones. --- diff --git a/chrootsh.c b/chrootsh.c index 5b12d0e..1898025 100644 --- a/chrootsh.c +++ b/chrootsh.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: chrootsh.c,v 1.3 1999/04/21 22:52:43 mdw Exp $ + * $Id: chrootsh.c,v 1.4 1999/04/22 00:30:27 mdw Exp $ * * Chroot gaol shell * @@ -27,6 +27,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: chrootsh.c,v $ + * Revision 1.4 1999/04/22 00:30:27 mdw + * Miscellanous tidying and security fixes. Lots of thanks due to Clive + * Jones. + * * Revision 1.3 1999/04/21 22:52:43 mdw * Added a pile of syslog stuff, so that admins can see what this thing is * doing. @@ -65,6 +69,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); } @@ -104,18 +109,24 @@ int main(int argc, char *argv[]) /* --- Check the user is meant to be chrooted --- */ - 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); + { + 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 --- */ @@ -126,8 +137,10 @@ int main(int argc, char *argv[]) *q = 0; if (chdir(p) || chroot(p)) { + int e = errno; syslog(LOG_ERR, "error entering chroot gaol: %m"); - fprintf(stderr, "%s: couldn't call chroot: %s", quis, strerror(errno)); + setuid(me); + fprintf(stderr, "%s: couldn't call chroot: %s\n", quis, strerror(e)); exit(EXIT_FAILURE); } setuid(me); @@ -136,22 +149,21 @@ int main(int argc, char *argv[]) /* --- Read the new password block --- */ - { - 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(); + 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 *)); @@ -160,6 +172,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)); @@ -169,6 +182,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 --- */ @@ -195,19 +218,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 -------------------------------------------------*/