3 * $Id: chrootsh.c,v 1.3 1999/04/21 22:52:43 mdw Exp $
7 * (c) 1999 Mark Wooding
10 /*----- Licensing notice --------------------------------------------------*
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 /*----- Revision history --------------------------------------------------*
29 * $Log: chrootsh.c,v $
30 * Revision 1.3 1999/04/21 22:52:43 mdw
31 * Added a pile of syslog stuff, so that admins can see what this thing is
34 * Revision 1.2 1999/04/21 09:07:55 mdw
35 * Fiddle with copyright messages so that they're correct.
37 * Revision 1.1.1.1 1999/04/20 00:19:04 mdw
42 /*----- Header files ------------------------------------------------------*/
49 #include <sys/types.h>
54 extern char **environ;
56 /*----- Main code ---------------------------------------------------------*/
59 # define CHROOTSH_PATH "/usr/bin/chrootsh"
62 static const char *quis = "chrootsh";
64 static void *xmalloc(size_t sz)
68 fprintf(stderr, "%s: not enough memory\n", quis);
74 static char *xstrdup(const char *p)
76 size_t sz = strlen(p) + 1;
77 char *q = xmalloc(sz);
82 int main(int argc, char *argv[])
90 /* --- Resolve the program name --- */
95 for (q = argv[0]; *q; q++) {
102 openlog(quis, LOG_PID | LOG_NDELAY, LOG_DAEMON);
105 /* --- Check the user is meant to be chrooted --- */
109 syslog(LOG_ERR, "executed by non-existant user (uid = %i)", (int)me);
110 fprintf(stderr, "%s: you don't exist. Go away.\n", quis);
113 if (strcmp(pw->pw_shell, CHROOTSH_PATH) != 0) {
114 syslog(LOG_ERR, "executed by non-chrooted user `%s'", pw->pw_name);
115 fprintf(stderr, "%s: you aren't a chrooted user\n", quis);
120 /* --- Chroot the user --- */
123 char *p = xstrdup(pw->pw_dir);
124 char *q = strstr(p, "/./");
128 if (chdir(p) || chroot(p)) {
129 syslog(LOG_ERR, "error entering chroot gaol: %m");
130 fprintf(stderr, "%s: couldn't call chroot: %s", quis, strerror(errno));
137 /* --- Read the new password block --- */
140 myname = xstrdup(pw->pw_name);
141 pw = getpwnam(myname);
144 "configuration error: user `%s' not defined in gaol", myname);
145 fprintf(stderr, "%s: you don't exist in the gaol\n", quis);
151 /* --- Now fiddle with environment strings and suchlike --- */
155 for (n = 0; environ[n]; n++)
157 env = xmalloc((n + 1) * sizeof(char *));
159 for (n = 0; environ[n]; n++) {
160 if (strncmp(environ[n], "HOME=", 5) == 0) {
161 char *p = xmalloc(6 + strlen(pw->pw_dir));
162 sprintf(p, "HOME=%s", pw->pw_dir);
164 } else if (strncmp(environ[n], "SHELL=", 6) == 0) {
165 char *p = xmalloc(7 + strlen(pw->pw_shell));
166 sprintf(p, "SHELL=%s", pw->pw_shell);
174 /* --- Finally, sort the argument list --- */
180 av = xmalloc((argc + 1) * sizeof(char *));
182 for (q = p; *q; q++) {
186 if (argv[0][0] == '-') {
187 q = xmalloc(2 + strlen(p));
194 for (i = 1; i <= argc; i++)
198 /* --- Change directory (again) --- */
200 if (chdir(pw->pw_dir))
201 fprintf(stderr, "No directory, logging in with HOME=/\n");
203 /* --- Run the real shell --- */
205 syslog(LOG_INFO, "chroot user `%s' logged in ok", myname);
207 execve(pw->pw_shell, av, env);
208 fprintf(stderr, "%s: couldn't exec `%s': %s",
209 quis, pw->pw_shell, strerror(errno));
210 return (EXIT_FAILURE);
213 /*----- That's all, folks -------------------------------------------------*/