3 * $Id: chrootsh.c,v 1.1 1999/04/20 00:19:04 mdw Exp $
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Chroot shell.
14 * chrootsh is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * chrootsh is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with chrootsh; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /*----- Revision history --------------------------------------------------*
31 * $Log: chrootsh.c,v $
32 * Revision 1.1 1999/04/20 00:19:04 mdw
37 /*----- Header files ------------------------------------------------------*/
44 #include <sys/types.h>
48 extern char **environ
;
50 /*----- Main code ---------------------------------------------------------*/
53 # define CHROOTSH_PATH "/usr/bin/chrootsh"
56 static const char *quis
= "chrootsh";
58 static void *xmalloc(size_t sz
)
62 fprintf(stderr
, "%s: not enough memory\n", quis
);
68 static char *xstrdup(const char *p
)
70 size_t sz
= strlen(p
) + 1;
71 char *q
= xmalloc(sz
);
76 int main(int argc
, char *argv
[])
83 /* --- Resolve the program name --- */
88 for (q
= argv
[0]; *q
; q
++) {
95 /* --- Check the user is meant to be chrooted --- */
99 fprintf(stderr
, "%s: you don't exist. Go away.\n", quis
);
102 if (strcmp(pw
->pw_shell
, CHROOTSH_PATH
) != 0) {
103 fprintf(stderr
, "%s: you aren't a chrooted user\n", quis
);
108 /* --- Chroot the user --- */
111 char *p
= xstrdup(pw
->pw_dir
);
112 char *q
= strstr(p
, "/./");
116 if (chdir(p
) || chroot(p
)) {
117 fprintf(stderr
, "%s: couldn't call chroot: %s", quis
, strerror(errno
));
124 /* --- Read the new password block --- */
127 char *p
= xstrdup(pw
->pw_name
);
131 fprintf(stderr
, "%s: you don't exist in the gaol\n", quis
);
137 /* --- Now fiddle with environment strings and suchlike --- */
141 for (n
= 0; environ
[n
]; n
++)
143 env
= xmalloc((n
+ 1) * sizeof(char *));
145 for (n
= 0; environ
[n
]; n
++) {
146 if (strncmp(environ
[n
], "HOME=", 5) == 0) {
147 char *p
= xmalloc(6 + strlen(pw
->pw_dir
));
148 sprintf(p
, "HOME=%s", pw
->pw_dir
);
150 } else if (strncmp(environ
[n
], "SHELL=", 6) == 0) {
151 char *p
= xmalloc(7 + strlen(pw
->pw_shell
));
152 sprintf(p
, "SHELL=%s", pw
->pw_shell
);
160 /* --- Finally, sort the argument list --- */
166 av
= xmalloc((argc
+ 1) * sizeof(char *));
168 for (q
= p
; *q
; q
++) {
172 if (argv
[0][0] == '-') {
173 q
= xmalloc(2 + strlen(p
));
180 for (i
= 1; i
<= argc
; i
++)
184 /* --- Change directory (again) --- */
186 if (chdir(pw
->pw_dir
))
187 fprintf(stderr
, "No directory, logging in with HOME=/\n");
189 /* --- Run the real shell --- */
191 execve(pw
->pw_shell
, av
, env
);
192 fprintf(stderr
, "%s: couldn't exec `%s': %s",
193 quis
, pw
->pw_shell
, strerror(errno
));
194 return (EXIT_FAILURE
);
197 /*----- That's all, folks -------------------------------------------------*/