Index: sbin/dumpon/Makefile =================================================================== --- sbin/dumpon/Makefile +++ sbin/dumpon/Makefile @@ -10,6 +10,12 @@ CFLAGS+=-DHAVE_CRYPTO .endif +.if ${MK_CASPER} != "no" +LIBADD+= casper +LIBADD+= cap_sysctl +CFLAGS+= -DWITH_CASPER +.endif + MAN= dumpon.8 .include Index: sbin/dumpon/dumpon.c =================================================================== --- sbin/dumpon/dumpon.c +++ sbin/dumpon/dumpon.c @@ -75,13 +75,22 @@ #include #ifdef HAVE_CRYPTO +#include +#include + #include #include #include #include #endif +static int netdump_fd = -1; static int verbose; +static const char *sysctlname = "kern.shutdown.dumpdevname"; + +#ifdef HAVE_CRYPTO +static cap_channel_t *capsysctl; +#endif static void _Noreturn usage(void) @@ -212,6 +221,8 @@ static void genkey(const char *pubkeyfile, struct diocskerneldump_arg *kdap) { + cap_channel_t *capcas; + void *caplimit; FILE *fp; RSA *pubkey; @@ -237,6 +248,26 @@ } #endif + capcas = cap_init(); + if (capcas == NULL) + err(1, "Unable to contact Casper"); + /* + * Allow listdumpdev() to display verbose output later. + */ + if (verbose) { + netdump_fd = open(_PATH_NETDUMP, O_RDONLY); + if (netdump_fd == -1 && errno != ENOENT) + err(EX_OSERR, "opening %s", _PATH_NETDUMP); + capsysctl = cap_service_open(capcas, "system.sysctl"); + if (capsysctl == NULL) + err(1, "Unable to open system.sysctl service"); + cap_close(capcas); + caplimit = cap_sysctl_limit_init(capsysctl); + (void)cap_sysctl_limit_name(caplimit, sysctlname, + CAP_SYSCTL_READ); + if (cap_sysctl_limit(caplimit) < 0) + err(1, "Unable to set system.sysctl limits"); + } if (caph_enter() < 0) err(1, "Unable to enter capability mode"); @@ -315,11 +346,16 @@ char dumpdev[PATH_MAX]; struct diocskerneldump_arg ndconf; size_t len; - const char *sysctlname = "kern.shutdown.dumpdevname"; - int fd; + int error; len = sizeof(dumpdev); - if (sysctlbyname(sysctlname, &dumpdev, &len, NULL, 0) != 0) { +#ifdef HAVE_CRYPTO + if (capsysctl != NULL) + error = cap_sysctlbyname(capsysctl, sysctlname, &dumpdev, &len, NULL, 0); + else +#endif + error = sysctlbyname(sysctlname, &dumpdev, &len, NULL, 0); + if (error != 0) { if (errno == ENOMEM) { err(EX_OSERR, "Kernel returned too large of a buffer for '%s'\n", sysctlname); @@ -344,16 +380,17 @@ /* If netdump is enabled, print the configuration parameters. */ if (verbose) { - fd = open(_PATH_NETDUMP, O_RDONLY); - if (fd < 0) { + if (netdump_fd == -1) + netdump_fd = open(_PATH_NETDUMP, O_RDONLY); + if (netdump_fd < 0) { if (errno != ENOENT) err(EX_OSERR, "opening %s", _PATH_NETDUMP); return; } - if (ioctl(fd, DIOCGKERNELDUMP, &ndconf) != 0) { + if (ioctl(netdump_fd, DIOCGKERNELDUMP, &ndconf) != 0) { if (errno != ENXIO) err(EX_OSERR, "ioctl(DIOCGKERNELDUMP)"); - (void)close(fd); + (void)close(netdump_fd); return; } @@ -366,7 +403,7 @@ printf("gateway address: %s\n", inet_ntop(ndconf.kda_af, &ndconf.kda_gateway, ip, sizeof(ip))); - (void)close(fd); + (void)close(netdump_fd); } }