Deleted Added
full compact
jail.c (194708) jail.c (194869)
1/*-
2 * Copyright (c) 1999 Poul-Henning Kamp.
3 * Copyright (c) 2009 James Gritton
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1999 Poul-Henning Kamp.
3 * Copyright (c) 2009 James Gritton
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/usr.sbin/jail/jail.c 194708 2009-06-23 14:39:51Z jamie $");
29__FBSDID("$FreeBSD: head/usr.sbin/jail/jail.c 194869 2009-06-24 18:18:35Z jamie $");
30
31#include <sys/param.h>
32#include <sys/jail.h>
33#include <sys/socket.h>
34#include <sys/sysctl.h>
30
31#include <sys/param.h>
32#include <sys/jail.h>
33#include <sys/socket.h>
34#include <sys/sysctl.h>
35#include <sys/uio.h>
36
37#include <arpa/inet.h>
38#include <netinet/in.h>
39
40#include <ctype.h>
41#include <err.h>
42#include <errno.h>
43#include <grp.h>
35
36#include <arpa/inet.h>
37#include <netinet/in.h>
38
39#include <ctype.h>
40#include <err.h>
41#include <errno.h>
42#include <grp.h>
43#include <jail.h>
44#include <login_cap.h>
45#include <netdb.h>
46#include <paths.h>
47#include <pwd.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <unistd.h>
52
44#include <login_cap.h>
45#include <netdb.h>
46#include <paths.h>
47#include <pwd.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <unistd.h>
52
53#define SJPARAM "security.jail.param"
54#define ERRMSG_SIZE 256
55
56struct param {
57 struct iovec name;
58 struct iovec value;
59};
60
61static struct param *params;
53static struct jailparam *params;
62static char **param_values;
63static int nparams;
64
65static char *ip4_addr;
66#ifdef INET6
67static char *ip6_addr;
68#endif
69

--- 38 unchanged lines hidden (view full) ---

108 if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0) \
109 err(1, "getgrouplist: %s", username); \
110} while (0)
111
112int
113main(int argc, char **argv)
114{
115 login_cap_t *lcap = NULL;
54static char **param_values;
55static int nparams;
56
57static char *ip4_addr;
58#ifdef INET6
59static char *ip6_addr;
60#endif
61

--- 38 unchanged lines hidden (view full) ---

100 if (getgrouplist(username, pwd->pw_gid, groups, &ngroups) != 0) \
101 err(1, "getgrouplist: %s", username); \
102} while (0)
103
104int
105main(int argc, char **argv)
106{
107 login_cap_t *lcap = NULL;
116 struct iovec rparams[2];
117 struct passwd *pwd = NULL;
118 gid_t *groups;
119 size_t sysvallen;
120 int ch, cmdarg, i, jail_set_flags, jid, ngroups, sysval;
121 int hflag, iflag, Jflag, lflag, rflag, uflag, Uflag;
122 long ngroups_max;
123 unsigned pi;
108 struct passwd *pwd = NULL;
109 gid_t *groups;
110 size_t sysvallen;
111 int ch, cmdarg, i, jail_set_flags, jid, ngroups, sysval;
112 int hflag, iflag, Jflag, lflag, rflag, uflag, Uflag;
113 long ngroups_max;
114 unsigned pi;
124 char *ep, *jailname, *securelevel, *username, *JidFile;
125 char errmsg[ERRMSG_SIZE], enforce_statfs[4];
115 char *jailname, *securelevel, *username, *JidFile;
116 char enforce_statfs[4];
126 static char *cleanenv;
127 const char *shell, *p = NULL;
128 FILE *fp;
129
130 hflag = iflag = Jflag = lflag = rflag = uflag = Uflag =
131 jail_set_flags = 0;
132 cmdarg = jid = -1;
133 jailname = securelevel = username = JidFile = cleanenv = NULL;

--- 37 unchanged lines hidden (view full) ---

171 break;
172 case 'c':
173 jail_set_flags |= JAIL_CREATE;
174 break;
175 case 'm':
176 jail_set_flags |= JAIL_UPDATE;
177 break;
178 case 'r':
117 static char *cleanenv;
118 const char *shell, *p = NULL;
119 FILE *fp;
120
121 hflag = iflag = Jflag = lflag = rflag = uflag = Uflag =
122 jail_set_flags = 0;
123 cmdarg = jid = -1;
124 jailname = securelevel = username = JidFile = cleanenv = NULL;

--- 37 unchanged lines hidden (view full) ---

162 break;
163 case 'c':
164 jail_set_flags |= JAIL_CREATE;
165 break;
166 case 'm':
167 jail_set_flags |= JAIL_UPDATE;
168 break;
169 case 'r':
179 jid = strtoul(optarg, &ep, 10);
180 if (!*optarg || *ep) {
181 *(const void **)&rparams[0].iov_base = "name";
182 rparams[0].iov_len = sizeof("name");
183 rparams[1].iov_base = optarg;
184 rparams[1].iov_len = strlen(optarg) + 1;
185 jid = jail_get(rparams, 2, 0);
186 if (jid < 0)
187 errx(1, "unknown jail: %s", optarg);
188 }
170 jid = jail_getid(optarg);
171 if (jid < 0)
172 errx(1, "%s", jail_errmsg);
189 rflag = 1;
190 break;
191 default:
192 usage();
193 }
194 }
195 argc -= optind;
196 argv += optind;

--- 78 unchanged lines hidden (view full) ---

275 }
276 }
277 if (ip4_addr != NULL)
278 set_param("ip4.addr", ip4_addr);
279#ifdef INET6
280 if (ip6_addr != NULL)
281 set_param("ip6.addr", ip6_addr);
282#endif
173 rflag = 1;
174 break;
175 default:
176 usage();
177 }
178 }
179 argc -= optind;
180 argv += optind;

--- 78 unchanged lines hidden (view full) ---

259 }
260 }
261 if (ip4_addr != NULL)
262 set_param("ip4.addr", ip4_addr);
263#ifdef INET6
264 if (ip6_addr != NULL)
265 set_param("ip6.addr", ip6_addr);
266#endif
283 errmsg[0] = 0;
284 set_param("errmsg", errmsg);
285
286 if (Jflag) {
287 fp = fopen(JidFile, "w");
288 if (fp == NULL)
289 errx(1, "Could not create JidFile: %s", JidFile);
290 }
267
268 if (Jflag) {
269 fp = fopen(JidFile, "w");
270 if (fp == NULL)
271 errx(1, "Could not create JidFile: %s", JidFile);
272 }
291 jid = jail_set(&params->name, 2 * nparams,
273 jid = jailparam_set(params, nparams,
292 jail_set_flags ? jail_set_flags : JAIL_CREATE | JAIL_ATTACH);
274 jail_set_flags ? jail_set_flags : JAIL_CREATE | JAIL_ATTACH);
293 if (jid < 0) {
294 if (errmsg[0] != '\0')
295 errx(1, "%s", errmsg);
296 err(1, "jail_set");
297 }
275 if (jid < 0)
276 errx(1, "%s", jail_errmsg);
298 if (iflag) {
299 printf("%d\n", jid);
300 fflush(stdout);
301 }
302 if (Jflag) {
303 if (jail_set_flags) {
304 fprintf(fp, "jid=%d", jid);
305 for (i = 0; i < nparams; i++)
277 if (iflag) {
278 printf("%d\n", jid);
279 fflush(stdout);
280 }
281 if (Jflag) {
282 if (jail_set_flags) {
283 fprintf(fp, "jid=%d", jid);
284 for (i = 0; i < nparams; i++)
306 if (strcmp(params[i].name.iov_base, "jid") &&
307 strcmp(params[i].name.iov_base, "errmsg")) {
285 if (strcmp(params[i].jp_name, "jid")) {
308 fprintf(fp, " %s",
286 fprintf(fp, " %s",
309 (char *)params[i].name.iov_base);
287 (char *)params[i].jp_name);
310 if (param_values[i]) {
311 putc('=', fp);
312 quoted_print(fp,
313 param_values[i]);
314 }
315 }
316 fprintf(fp, "\n");
317 } else {
318 for (i = 0; i < nparams; i++)
288 if (param_values[i]) {
289 putc('=', fp);
290 quoted_print(fp,
291 param_values[i]);
292 }
293 }
294 fprintf(fp, "\n");
295 } else {
296 for (i = 0; i < nparams; i++)
319 if (!strcmp(params[i].name.iov_base, "path"))
297 if (!strcmp(params[i].jp_name, "path"))
320 break;
321#ifdef INET6
322 fprintf(fp, "%d\t%s\t%s\t%s%s%s\t%s\n",
323 jid, i < nparams
298 break;
299#ifdef INET6
300 fprintf(fp, "%d\t%s\t%s\t%s%s%s\t%s\n",
301 jid, i < nparams
324 ? (char *)params[i].value.iov_base : argv[0],
302 ? (char *)params[i].jp_value : argv[0],
325 argv[1], ip4_addr ? ip4_addr : "",
326 ip4_addr && ip4_addr[0] && ip6_addr && ip6_addr[0]
327 ? "," : "", ip6_addr ? ip6_addr : "", argv[3]);
328#else
329 fprintf(fp, "%d\t%s\t%s\t%s\t%s\n",
330 jid, i < nparams
303 argv[1], ip4_addr ? ip4_addr : "",
304 ip4_addr && ip4_addr[0] && ip6_addr && ip6_addr[0]
305 ? "," : "", ip6_addr ? ip6_addr : "", argv[3]);
306#else
307 fprintf(fp, "%d\t%s\t%s\t%s\t%s\n",
308 jid, i < nparams
331 ? (char *)params[i].value.iov_base : argv[0],
309 ? (char *)params[i].jp_value : argv[0],
332 argv[1], ip4_addr ? ip4_addr : "", argv[3]);
333#endif
334 }
335 (void)fclose(fp);
336 }
337 if (cmdarg < 0)
338 exit(0);
339 if (username != NULL) {

--- 152 unchanged lines hidden (view full) ---

492 }
493 if (qc)
494 putc(qc, fp);
495}
496
497static void
498set_param(const char *name, char *value)
499{
310 argv[1], ip4_addr ? ip4_addr : "", argv[3]);
311#endif
312 }
313 (void)fclose(fp);
314 }
315 if (cmdarg < 0)
316 exit(0);
317 if (username != NULL) {

--- 152 unchanged lines hidden (view full) ---

470 }
471 if (qc)
472 putc(qc, fp);
473}
474
475static void
476set_param(const char *name, char *value)
477{
500 struct param *param;
501 char *ep, *p;
502 size_t buflen, mlen;
503 int i, nval, mib[CTL_MAXNAME];
504 struct {
505 int i;
506 char s[MAXPATHLEN];
507 } buf;
478 struct jailparam *param;
479 int i;
508
509 static int paramlistsize;
510
511 /* Separate the name from the value, if not done already. */
512 if (name == NULL) {
513 name = value;
514 if ((value = strchr(value, '=')))
515 *value++ = '\0';
516 }
517
518 /* Check for repeat parameters */
519 for (i = 0; i < nparams; i++)
480
481 static int paramlistsize;
482
483 /* Separate the name from the value, if not done already. */
484 if (name == NULL) {
485 name = value;
486 if ((value = strchr(value, '=')))
487 *value++ = '\0';
488 }
489
490 /* Check for repeat parameters */
491 for (i = 0; i < nparams; i++)
520 if (!strcmp(name, params[i].name.iov_base)) {
492 if (!strcmp(name, params[i].jp_name)) {
493 jailparam_free(params + i, 1);
521 memcpy(params + i, params + i + 1,
494 memcpy(params + i, params + i + 1,
522 (--nparams - i) * sizeof(struct param));
495 (--nparams - i) * sizeof(struct jailparam));
523 break;
524 }
525
526 /* Make sure there is room for the new param record. */
527 if (!nparams) {
528 paramlistsize = 32;
529 params = malloc(paramlistsize * sizeof(*params));
530 param_values = malloc(paramlistsize * sizeof(*param_values));

--- 6 unchanged lines hidden (view full) ---

537 paramlistsize * sizeof(*param_values));
538 if (params == NULL)
539 err(1, "realloc");
540 }
541
542 /* Look up the paramter. */
543 param_values[nparams] = value;
544 param = params + nparams++;
496 break;
497 }
498
499 /* Make sure there is room for the new param record. */
500 if (!nparams) {
501 paramlistsize = 32;
502 params = malloc(paramlistsize * sizeof(*params));
503 param_values = malloc(paramlistsize * sizeof(*param_values));

--- 6 unchanged lines hidden (view full) ---

510 paramlistsize * sizeof(*param_values));
511 if (params == NULL)
512 err(1, "realloc");
513 }
514
515 /* Look up the paramter. */
516 param_values[nparams] = value;
517 param = params + nparams++;
545 *(const void **)&param->name.iov_base = name;
546 param->name.iov_len = strlen(name) + 1;
547 /* Trivial values - no value or errmsg. */
548 if (value == NULL) {
549 param->value.iov_base = NULL;
550 param->value.iov_len = 0;
551 return;
552 }
553 if (!strcmp(name, "errmsg")) {
554 param->value.iov_base = value;
555 param->value.iov_len = ERRMSG_SIZE;
556 return;
557 }
558 mib[0] = 0;
559 mib[1] = 3;
560 snprintf(buf.s, sizeof(buf.s), SJPARAM ".%s", name);
561 mlen = sizeof(mib) - 2 * sizeof(int);
562 if (sysctl(mib, 2, mib + 2, &mlen, buf.s, strlen(buf.s)) < 0)
563 errx(1, "unknown parameter: %s", name);
564 mib[1] = 4;
565 buflen = sizeof(buf);
566 if (sysctl(mib, (mlen / sizeof(int)) + 2, &buf, &buflen, NULL, 0) < 0)
567 err(1, "sysctl(0.4.%s)", name);
568 /*
569 * See if this is an array type.
570 * Treat non-arrays as an array of one.
571 */
572 p = strchr(buf.s, '\0');
573 nval = 1;
574 if (p - 2 >= buf.s && !strcmp(p - 2, ",a")) {
575 if (value[0] == '\0' ||
576 (value[0] == '-' && value[1] == '\0')) {
577 param->value.iov_base = value;
578 param->value.iov_len = 0;
579 return;
580 }
581 p[-2] = 0;
582 for (p = strchr(value, ','); p; p = strchr(p + 1, ',')) {
583 *p = '\0';
584 nval++;
585 }
586 }
587
588 /* Set the values according to the parameter type. */
589 switch (buf.i & CTLTYPE) {
590 case CTLTYPE_INT:
591 case CTLTYPE_UINT:
592 param->value.iov_len = nval * sizeof(int);
593 break;
594 case CTLTYPE_LONG:
595 case CTLTYPE_ULONG:
596 param->value.iov_len = nval * sizeof(long);
597 break;
598 case CTLTYPE_STRUCT:
599 if (!strcmp(buf.s, "S,in_addr"))
600 param->value.iov_len = nval * sizeof(struct in_addr);
601#ifdef INET6
602 else if (!strcmp(buf.s, "S,in6_addr"))
603 param->value.iov_len = nval * sizeof(struct in6_addr);
604#endif
605 else
606 errx(1, "%s: unknown parameter structure (%s)",
607 name, buf.s);
608 break;
609 case CTLTYPE_STRING:
610 if (!strcmp(name, "path")) {
611 param->value.iov_base = malloc(MAXPATHLEN);
612 if (param->value.iov_base == NULL)
613 err(1, "malloc");
614 if (realpath(value, param->value.iov_base) == NULL)
615 err(1, "%s: realpath(%s)", name, value);
616 if (chdir(param->value.iov_base) != 0)
617 err(1, "chdir: %s",
618 (char *)param->value.iov_base);
619 } else
620 param->value.iov_base = value;
621 param->value.iov_len = strlen(param->value.iov_base) + 1;
622 return;
623 default:
624 errx(1, "%s: unknown parameter type %d (%s)",
625 name, buf.i, buf.s);
626 }
627 param->value.iov_base = malloc(param->value.iov_len);
628 for (i = 0; i < nval; i++) {
629 switch (buf.i & CTLTYPE) {
630 case CTLTYPE_INT:
631 ((int *)param->value.iov_base)[i] =
632 strtol(value, &ep, 10);
633 if (ep[0] != '\0')
634 errx(1, "%s: non-integer value \"%s\"",
635 name, value);
636 break;
637 case CTLTYPE_UINT:
638 ((unsigned *)param->value.iov_base)[i] =
639 strtoul(value, &ep, 10);
640 if (ep[0] != '\0')
641 errx(1, "%s: non-integer value \"%s\"",
642 name, value);
643 break;
644 case CTLTYPE_LONG:
645 ((long *)param->value.iov_base)[i] =
646 strtol(value, &ep, 10);
647 if (ep[0] != '\0')
648 errx(1, "%s: non-integer value \"%s\"",
649 name, value);
650 break;
651 case CTLTYPE_ULONG:
652 ((unsigned long *)param->value.iov_base)[i] =
653 strtoul(value, &ep, 10);
654 if (ep[0] != '\0')
655 errx(1, "%s: non-integer value \"%s\"",
656 name, value);
657 break;
658 case CTLTYPE_STRUCT:
659 if (!strcmp(buf.s, "S,in_addr")) {
660 if (inet_pton(AF_INET, value,
661 &((struct in_addr *)
662 param->value.iov_base)[i]) != 1)
663 errx(1, "%s: not an IPv4 address: %s",
664 name, value);
665 }
666#ifdef INET6
667 else if (!strcmp(buf.s, "S,in6_addr")) {
668 if (inet_pton(AF_INET6, value,
669 &((struct in6_addr *)
670 param->value.iov_base)[i]) != 1)
671 errx(1, "%s: not an IPv6 address: %s",
672 name, value);
673 }
674#endif
675 }
676 if (i > 0)
677 value[-1] = ',';
678 value = strchr(value, '\0') + 1;
679 }
518 if (jailparam_init(param, name) < 0 ||
519 jailparam_import(param, value) < 0)
520 errx(1, "%s", jail_errmsg);
680}
681
682static void
683usage(void)
684{
685
686 (void)fprintf(stderr,
687 "usage: jail [-d] [-h] [-i] [-J jid_file] "
688 "[-l -u username | -U username]\n"
689 " [-c | -m] param=value ... [command=command ...]\n"
690 " jail [-r jail]\n");
691 exit(1);
692}
521}
522
523static void
524usage(void)
525{
526
527 (void)fprintf(stderr,
528 "usage: jail [-d] [-h] [-i] [-J jid_file] "
529 "[-l -u username | -U username]\n"
530 " [-c | -m] param=value ... [command=command ...]\n"
531 " jail [-r jail]\n");
532 exit(1);
533}