341724c32a3b3a141afeed4d7f5c0d6b03c7f439
3 * $Id: chrootsh.c,v 1.2 1999/04/21 09:07:55 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.2 1999/04/21 09:07:55 mdw
31 * Fiddle with copyright messages so that they're correct.
33 * Revision 1.1.1.1 1999/04/20 00:19:04 mdw
38 /*----- Header files ------------------------------------------------------*/
45 #include <sys/types.h>
49 extern char **environ
;
51 /*----- Main code ---------------------------------------------------------*/
54 # define CHROOTSH_PATH "/usr/bin/chrootsh"
57 static const char *quis
= "chrootsh";
59 static void *xmalloc(size_t sz
)
63 fprintf(stderr
, "%s: not enough memory\n", quis
);
69 static char *xstrdup(const char *p
)
71 size_t sz
= strlen(p
) + 1;
72 char *q
= xmalloc(sz
);
77 int main(int argc
, char *argv
[])
84 /* --- Resolve the program name --- */
89 for (q
= argv
[0]; *q
; q
++) {
96 /* --- Check the user is meant to be chrooted --- */
100 fprintf(stderr
, "%s: you don't exist. Go away.\n", quis
);
103 if (strcmp(pw
->pw_shell
, CHROOTSH_PATH
) != 0) {
104 fprintf(stderr
, "%s: you aren't a chrooted user\n", quis
);
109 /* --- Chroot the user --- */
112 char *p
= xstrdup(pw
->pw_dir
);
113 char *q
= strstr(p
, "/./");
117 if (chdir(p
) || chroot(p
)) {
118 fprintf(stderr
, "%s: couldn't call chroot: %s", quis
, strerror(errno
));
125 /* --- Read the new password block --- */
128 char *p
= xstrdup(pw
->pw_name
);
132 fprintf(stderr
, "%s: you don't exist in the gaol\n", quis
);
138 /* --- Now fiddle with environment strings and suchlike --- */
142 for (n
= 0; environ
[n
]; n
++)
144 env
= xmalloc((n
+ 1) * sizeof(char *));
146 for (n
= 0; environ
[n
]; n
++) {
147 if (strncmp(environ
[n
], "HOME=", 5) == 0) {
148 char *p
= xmalloc(6 + strlen(pw
->pw_dir
));
149 sprintf(p
, "HOME=%s", pw
->pw_dir
);
151 } else if (strncmp(environ
[n
], "SHELL=", 6) == 0) {
152 char *p
= xmalloc(7 + strlen(pw
->pw_shell
));
153 sprintf(p
, "SHELL=%s", pw
->pw_shell
);
161 /* --- Finally, sort the argument list --- */
167 av
= xmalloc((argc
+ 1) * sizeof(char *));
169 for (q
= p
; *q
; q
++) {
173 if (argv
[0][0] == '-') {
174 q
= xmalloc(2 + strlen(p
));
181 for (i
= 1; i
<= argc
; i
++)
185 /* --- Change directory (again) --- */
187 if (chdir(pw
->pw_dir
))
188 fprintf(stderr
, "No directory, logging in with HOME=/\n");
190 /* --- Run the real shell --- */
192 execve(pw
->pw_shell
, av
, env
);
193 fprintf(stderr
, "%s: couldn't exec `%s': %s",
194 quis
, pw
->pw_shell
, strerror(errno
));
195 return (EXIT_FAILURE
);
198 /*----- That's all, folks -------------------------------------------------*/