Index: bin/cat/Makefile =================================================================== --- bin/cat/Makefile +++ bin/cat/Makefile @@ -15,4 +15,11 @@ HAS_TESTS= SUBDIR.${MK_TESTS}+= tests +.if ${MK_CASPER} != "no" && !defined(RESCUE) && !defined(BOOTSTRAPPING) +LIBADD+= casper +LIBADD+= cap_fileargs +LIBADD+= cap_net +CFLAGS+=-DWITH_CASPER +.endif + .include Index: bin/cat/cat.c =================================================================== --- bin/cat/cat.c +++ bin/cat/cat.c @@ -48,6 +48,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #ifndef NO_UDOM_SUPPORT @@ -56,6 +57,7 @@ #include #endif +#include #include #include #include @@ -68,9 +70,14 @@ #include #include +#include +#include +#include + static int bflag, eflag, lflag, nflag, sflag, tflag, vflag; static int rval; static const char *filename; +static fileargs_t *fa; static void usage(void) __dead2; static void scanfiles(char *argv[], int cooked); @@ -78,6 +85,8 @@ static void raw_cat(int); #ifndef NO_UDOM_SUPPORT +static cap_channel_t *capnet; + static int udom_open(const char *path, int flags); #endif @@ -110,6 +119,51 @@ #define SUPPORTED_FLAGS "belnstuv" #endif +#ifndef NO_UDOM_SUPPORT +static void +init_casper_net(cap_channel_t *casper) +{ + cap_net_limit_t *limit; + int familylimit; + + capnet = cap_service_open(casper, "system.net"); + + limit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | + CAPNET_CONNECTDNS); + if (limit == NULL) + err(EXIT_FAILURE, "Unable to create limits"); + + familylimit = AF_LOCAL; + cap_net_limit_name2addr_family(limit, &familylimit, 1); + + if (cap_net_limit(limit) < 0) + err(EXIT_FAILURE, "Unable to apply limits"); +} +#endif + +static void +init_casper(int argc, char *argv[]) +{ + cap_channel_t *casper; + cap_rights_t rights; + + casper = cap_init(); + if (casper == NULL) + err(EXIT_FAILURE, "casper init"); + + fa = fileargs_cinit(casper, argc, argv, O_RDONLY, 0, + cap_rights_init(&rights, CAP_READ | CAP_FCNTL), + FA_OPEN | FA_REALPATH); + if (fa == NULL) + err(EXIT_FAILURE, "fileargs init"); + +#ifndef NO_UDOM_SUPPORT + init_casper_net(casper); +#endif + + cap_close(casper); +} + int main(int argc, char *argv[]) { @@ -148,6 +202,7 @@ usage(); } argv += optind; + argc -= optind; if (lflag) { stdout_lock.l_len = 0; @@ -158,6 +213,13 @@ err(EXIT_FAILURE, "stdout"); } + init_casper(argc, argv); + + caph_cache_catpages(); + + if (caph_enter_casper() < 0) + err(EXIT_FAILURE, "capsicum"); + if (bflag || eflag || nflag || sflag || tflag || vflag) scanfiles(argv, 1); else @@ -192,7 +254,7 @@ fd = STDIN_FILENO; } else { filename = path; - fd = open(path, O_RDONLY); + fd = fileargs_open(fa, path); #ifndef NO_UDOM_SUPPORT if (fd < 0 && errno == EOPNOTSUPP) fd = udom_open(path, O_RDONLY); @@ -368,9 +430,11 @@ */ bzero(&hints, sizeof(hints)); hints.ai_family = AF_LOCAL; - if (realpath(path, rpath) == NULL) + + if (fileargs_realpath(fa, path, rpath) == NULL) return (-1); - error = getaddrinfo(rpath, NULL, &hints, &res0); + + error = cap_getaddrinfo(capnet, rpath, NULL, &hints, &res0); if (error) { warn("%s", gai_strerror(error)); errno = EINVAL; @@ -383,7 +447,7 @@ freeaddrinfo(res0); return (-1); } - error = connect(fd, res->ai_addr, res->ai_addrlen); + error = cap_connect(capnet, fd, res->ai_addr, res->ai_addrlen); if (error == 0) break; else {